home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / quicktime / quicktime vr / vrscript.win / vrscript.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  145.6 KB  |  4,139 lines

  1. //////////
  2. //
  3. //    File:        VRScript.c
  4. //
  5. //    Contains:    Functions for script file processing.
  6. //
  7. //    Written by:    Tim Monroe
  8. //
  9. //    Copyright:    © 1997-1999 by Apple Computer, Inc., all rights reserved.
  10. //
  11. //    Change History (most recent first):
  12. //
  13. //       <54>         04/05/99        rtm        added kQTVRBackBufferHorizontal to flags in _InstallBackBufferImagingProc;
  14. //                                        from now on, we assume that our back buffer is horizontal and we no longer
  15. //                                        support real-time rotation of back buffer movies
  16. //       <53>         03/04/99        rtm        added VRScript_MoviePrePrerollCompleteProc, based on code from Tom Dowdy
  17. //       <52>         01/04/99        rtm        changed AtClickHS command into AtClickHSID and AtClickHSType commands
  18. //       <51>         12/17/98        rtm        removed VRScript_SetHotSpotState (moved code into _ProcessScriptCommandLine);
  19. //                                        added VRScript_SetCurrentDirectory and SetCurrentDirectory command
  20. //       <50>         12/16/98        rtm        tweaked VRScript_DeleteListOfType
  21. //       <49>         12/07/98        rtm        fixed VRScript_SetCurrentMovie to work with URLs to wired movies
  22. //       <48>         12/02/98        rtm        added VRScript_SetCurrentMovie; added URLUtilities.c to project
  23. //       <47>         11/28/98        rtm        reworked parser in VRScript_ProcessScriptCommandLine to use a hash table,
  24. //                                        using routines in VRHash.c; the basic idea was inspired by Jon Summers' code
  25. //                                        in his mTropolis VRScript MOD, but my implementation is different from his 
  26. //       <46>         11/24/98        rtm        added SetTrackState, SetTrackLayer, SetMovieTime, SetMovieRate, 
  27. //                                        and SetMovieTimeScale commands
  28. //       <45>         11/19/98        rtm        added VRScript_OpenCommandLineScriptFile, to support scripts dropped
  29. //                                        onto the Windows version
  30. //       <44>         11/18/98        rtm        removed some variable initializations to work around CW compiler bugs
  31. //       <43>         09/04/98        rtm        added SetTrackVolume
  32. //       <42>         06/19/98        rtm        added support for clicking on sprites in sprite tracks, using code from
  33. //                                        QTSprites sample; added theTolerance parameter to VRScript_FloatsAreEqual
  34. //       <41>         04/09/98        rtm        added check for empty command lines in VRScript_ProcessScriptCommandLine
  35. //       <40>         04/06/98        rtm        added Destroy3DObject command, based loosely on code from Bill Meikle
  36. //       <39>         03/12/98        rtm        added AtClickCustomButton to handle user clicks on the custom controller button
  37. //       <38>         03/09/98        rtm        added VRScript_FloatsAreEqual
  38. //       <37>         02/25/98        rtm        revised VRScript_EnteringNodeProc to call MoviesTask instead of QTVRUpdate
  39. //       <36>         12/12/97        rtm        fixed VRScript_FindAndOpenQTVRMovieFile (was opening the movie file
  40. //                                        instead of allowing DoCreateMovieWindow to do so)
  41. //       <35>         10/29/97        rtm        finished adding support for QuickTime video effects
  42. //       <34>         10/27/97        rtm        began adding support for QuickTime video effects
  43. //       <33>         10/06/97        rtm        fixed bug in replace cursor commands (wouldn't restore original
  44. //                                        cursors if a click on the hot spot caused the node to be exited)
  45. //       <32>         09/10/97        rtm        made changes necessary to compile for Windows execution
  46. //       <31>         07/21/97        rtm        added VRScript_DumpUnexpiredCommands
  47. //       <30>         07/17/97        rtm        revised all list-walking code to avoid dangling pointers
  48. //       <29>         07/15/97        rtm        reworked VRScript_MouseOverHotSpotProc to use a single while loop
  49. //       <28>         07/14/97        rtm        fixed SetHotSpotTypeCursors to use OSTypes
  50. //       <27>         07/12/97        rtm        fixed a bug in VRScript_FindAndOpenQTVRMovieFile
  51. //       <26>         07/11/97        rtm        added support for encoded commands
  52. //       <25>         07/08/97        rtm        added SetHotSpotTypeCursors command
  53. //       <24>         07/07/97        rtm        added ReplaceResource and SetHotSpotIDCursors commands
  54. //       <23>         06/19/97        rtm        added PlaySceneSound and PlaySceneQTMidi, for persistent sounds
  55. //       <22>         06/13/97        rtm        added code to make sure QD3D present before executing 3D commands
  56. //       <21>         06/12/97        rtm        added VRScript_FindAndOpenQTVRMovieFile
  57. //       <20>         06/05/97        rtm        added VRScript_SetControllerButtonState;
  58. //                                        changed semantics of SetVariable and If commands
  59. //       <19>         06/04/97        rtm        added Mode parameter to SetPanTiltZoom;
  60. //       <18>         05/30/97        rtm        added script-defined variables (SetVariable and If commands)
  61. //       <17>         05/22/97        rtm        added ability to cancel node exit to VRScript_LeavingNodeProc
  62. //       <16>         05/01/97        rtm        code clean-up: put list heads into an array
  63. //       <15>         04/28/97        rtm        added support for QuickTime MIDI files
  64. //       <14>         04/17/97        rtm        added VRScript_DelistEntry; added fMaxExecutions to some commands
  65. //       <13>         04/10/97        rtm        added 3D object and 3D sound "Set" calls
  66. //       <12>         04/07/97        rtm        added SetResizeState
  67. //       <11>         04/02/97        rtm        added support for 3DMF files
  68. //       <10>         04/01/97        rtm        added VRScript_CheckForAngleCommands
  69. //       <9>         03/31/97        rtm        added node-entry and node-exit command support;
  70. //                                        added support for additional imaging and interaction properties
  71. //       <8>         03/21/97        rtm        added VRScript_SetHotSpotState
  72. //       <7>         03/17/97        rtm        localized embedded QuickTime movie sounds
  73. //       <6>         03/13/97        rtm        reworked hot spot sounds; fixed code for 680x0 compilation;
  74. //                                        added support for angle commands
  75. //       <5>         03/12/97        rtm        added support for mouse-over hot spot commands, external resource files,
  76. //                                        hot spot click commands, and QT movies;
  77. //       <4>         03/11/97        rtm        added support for timed commands (cool!)
  78. //       <3>         03/10/97        rtm        added support for controller bar, localized sounds, and overlay pictures
  79. //       <2>         03/07/97        rtm        got hot spot sounds working (except for any options)
  80. //       <1>         03/06/97        rtm        first file
  81. //
  82. //
  83. //    This file contain functions that support an external text script file for driving QuickTime VR movies.
  84. //  The script file contains one command per line; a command line is a command word followed by one or more
  85. //    command parameters. The number and meaning of the parameters depends on the command word. See the file 
  86. //    "Script Syntax" for a complete description of the scripting language.
  87. //
  88. //////////
  89.  
  90. //     TO DO:
  91. //    + finish hide region code
  92. //
  93.  
  94. // header files
  95. #include <stdio.h>
  96. #include <ctype.h>
  97. #include <stdlib.h>
  98. #include <string.h>
  99. #include <math.h>
  100.  
  101. #include "ComApplication.h"
  102.  
  103. // header files for special features
  104. #include "VRSound.h"
  105. #include "VRPicture.h"
  106. #include "VRMovies.h"
  107. #include "VR3DObjects.h"
  108. #include "VR3DTexture.h"
  109. #include "VREffects.h"
  110. #include "VRHash.h"
  111.  
  112. #include "VRScript.h"
  113.  
  114. // global variables
  115. Boolean                    gReadingScriptFile;                        // are we reading a script file?
  116. char                    gScriptFileName[kMaxFileNameLength];    // the name of the script file
  117. MovieController            gPreviousMC = NULL;                        // a controller that's been replaced by a call to ReplaceMainMovie                
  118. Movie                    gPreviousMovie = NULL;                    // a movie that's been replaced by a call to ReplaceMainMovie        
  119.  
  120. extern Boolean            gHasSoundSprockets;                        // is SoundSprockets available?
  121. extern Boolean            gHasSoundManager30;                        // is Sound Manager version 3.0 (or greater) available?
  122. extern Boolean            gHasQuickDraw3D;                        // is QuickDraw 3D available?
  123. extern Boolean            gHasQuickDraw3D15;                        // is QuickDraw 3D version 1.5 (or greater) available?
  124. extern Boolean            gHasQTVideoEffects;                        // are the QuickTime video effects available?
  125.  
  126. extern long                gAbsoluteElapsedTime;
  127. extern long                gNodeStartingTime;
  128. extern long                gNodeElapsedTime;
  129.  
  130. extern Rect                gLimitRect;                                // max size for any window
  131.  
  132.  
  133. //////////
  134. //
  135. // VRScript_OpenScriptFile
  136. // Open the external script file and process the commands (one command per line).
  137. //
  138. //////////
  139.  
  140. void VRScript_OpenScriptFile (WindowObject theWindowObject, char *theFileName)
  141. {
  142.     FILE        *myFile;
  143.     char        myString[kMaxCmdLineLength];
  144.     
  145.     if (theFileName == NULL)
  146.         return;
  147.         
  148.     myFile = fopen(theFileName, "r");
  149.     if (myFile == NULL)
  150.         return;
  151.  
  152.     gReadingScriptFile = true;
  153.  
  154.     while (fgets(myString, sizeof(myString), myFile) != NULL)
  155.         VRScript_ProcessScriptCommandLine(theWindowObject, myString);
  156.  
  157.     gReadingScriptFile = false;
  158.  
  159.     fclose(myFile);
  160. }
  161.  
  162.  
  163. #if TARGET_OS_WIN32
  164. //////////
  165. //
  166. // VRScript_OpenCommandLineScriptFile
  167. // Parse the command line when the application first starts up and
  168. // open as script files any files specified on the command line.
  169. //
  170. // Based on the routine DoOpenCommandLineMovies in WinFramework.c.
  171. //
  172. //////////
  173.  
  174. void VRScript_OpenCommandLineScriptFile (LPSTR theCmdLine)
  175. {
  176. #pragma unused(theCmdLine)
  177.     LPSTR                myCmdLine;
  178.     FSSpec                myFSSpec;
  179.     WIN32_FIND_DATA        myFile;
  180.     HANDLE                myFindFile;
  181.     char                 myFilePath[MAX_PATH];
  182.     
  183.     // get the command line for the current process
  184.     myCmdLine = GetCommandLine();
  185.  
  186.     // parse the command line
  187.     if (*myCmdLine) {
  188.         LPSTR            myTempLine;
  189.         
  190.         // the string preceding any white space is the name of the module (that is, the application)
  191.         myTempLine = strchr(myCmdLine, ' ');
  192.         if (myTempLine) {
  193.             myCmdLine = myTempLine;                  // skip the name of the application
  194.             while (*myCmdLine == ' ')
  195.                 myCmdLine++;                        // skip spaces to end of string or to first command
  196.  
  197.             while (*myCmdLine != '\0') {
  198.                 char     myFileName[MAX_PATH];
  199.                 char     myTempName[MAX_PATH];
  200.                 char     myBuffName[MAX_PATH];
  201.                 int     myIndex;
  202.                 
  203.                 // read thru the remaining string to find file names
  204.                 for (myIndex = 0; *myCmdLine != '\0'; myIndex++, myCmdLine++) {
  205.                     // if we encounter a space character, it might be a filename delimiter or a space in the filename;
  206.                     // we'll try to open the filename we have so far to see whether it's a valid filename; if not, the
  207.                     // space must be part of the filename we're constructing
  208.                     if (*myCmdLine == ' ') {
  209.                         HANDLE                myFindFile;
  210.                         WIN32_FIND_DATA        myFile;
  211.                     
  212.                         myTempName[myIndex] = '\0';
  213.                         strcpy(myBuffName, myTempName);
  214.                         
  215.                         myFindFile = FindFirstFile(myBuffName, &myFile);
  216.                         if (myFindFile != INVALID_HANDLE_VALUE) {
  217.                             // we found a file having the specified name; close our file search and
  218.                             // break out of our character-gobbling loop (since we've got a valid filename)
  219.                             FindClose(myFindFile);
  220.                             break;
  221.                         }
  222.                     }
  223.                 
  224.                     // if we made it here, *myCmdLine is part of the filename (possibly a space)
  225.                     myFileName[myIndex] = myTempName[myIndex] = *myCmdLine;
  226.                 }
  227.                 
  228.                 if (*myCmdLine != '\0')
  229.                     myCmdLine++;
  230.                 
  231.                 // add a terminating NULL character
  232.                 myFileName[myIndex] = '\0';
  233.  
  234.                 // myFileName is in 8.3 form; call FindFirstFile again to convert it to a long name
  235.                 // and then make an FSSpec record using the long file name
  236.                 
  237.                 // get the directory path
  238.                 NativePathNameToFSSpec(myFileName, &myFSSpec, 0L);
  239.                 FSSpecToNativePathName(&myFSSpec, myFilePath, MAX_PATH, kDirectoryPathOnly);
  240.                 
  241.                 myFindFile = FindFirstFile(myFileName, &myFile);
  242.                 if (myFindFile != INVALID_HANDLE_VALUE) {
  243.                     strcat(myFilePath, "\\");                    // the path separator
  244.                     strcat(myFilePath, myFile.cFileName);
  245.                     NativePathNameToFSSpec(myFilePath, &myFSSpec, 0L);
  246.                     FindClose(myFindFile);
  247.                 } else {
  248.                     // if FindFirstFile fails, just use the 8.3 name
  249.                     NativePathNameToFSSpec(myFileName, &myFSSpec, 0L);
  250.                 }
  251.  
  252.                 // open the script file; get the QTVR movie specified in it
  253.                 VRScript_FindAndOpenQTVRMovieFile(&myFSSpec);
  254.             }
  255.  
  256.         } else
  257.             myCmdLine += strlen(myCmdLine);           // point to NULL
  258.     }
  259. }
  260. #endif    // TARGET_OS_WIN32
  261.  
  262.  
  263. //////////
  264. //
  265. // VRScript_FindAndOpenQTVRMovieFile
  266. // Open the specified script file and look for the first OpenQTVRMovieFile command in it;
  267. // open the specified movie file if one is found.
  268. //
  269. //////////
  270.  
  271. void VRScript_FindAndOpenQTVRMovieFile (FSSpec *theFSSpecPtr)
  272. {
  273.     FILE        *myFile = NULL;
  274.     char        myString[kMaxCmdLineLength];
  275.     char        myCommand[kMaxCmdWordLength];
  276.     
  277.     // set the default directory and volume to be those of the script file, not the application
  278.     VRScript_SetCurrentDirectory(theFSSpecPtr);
  279.     
  280.     // convert the filename to a C string
  281.     memcpy(gScriptFileName, &theFSSpecPtr->name[1], theFSSpecPtr->name[0]);
  282.     gScriptFileName[theFSSpecPtr->name[0]] = '\0';
  283.     
  284.     // open the script file            
  285.     myFile = fopen(gScriptFileName, "r");
  286.     if (myFile == NULL)
  287.         return;
  288.  
  289.     // search through the script file for a line beginning "OpenQTVRMovieFile"
  290.     while (fgets(myString, sizeof(myString), myFile) != NULL) {
  291.     
  292.         // get the command word
  293.         sscanf(myString, "%s ", myCommand);
  294.         if (strlen(myCommand) == 0)
  295.             break;
  296.     
  297.          // open the specified VR movie file
  298.         if (strcmp(myCommand, "OpenQTVRMovieFile") == 0) {
  299.             char        myPathName[kMaxFileNameLength];
  300.             UInt32        myOptions;
  301.             FSSpec        myFSSpec;
  302.  
  303.             sscanf(myString, "%*s %ld %s", &myOptions, myPathName);
  304.             VRScript_UnpackString(myPathName);
  305.             
  306.             // create an FSSpec that picks out the QTVR movie file,
  307.             // in the same directory as the script file
  308.             FSMakeFSSpec(theFSSpecPtr->vRefNum, theFSSpecPtr->parID, c2pstr(myPathName), &myFSSpec);
  309.                         
  310.             // now act as if "Open" were chosen from the File menu....
  311.             DoCreateMovieWindow(NULL, &myFSSpec);
  312.             
  313.             // break out of the while loop
  314.             break;
  315.         }
  316.     }
  317.     
  318.     fclose(myFile);
  319. }
  320.  
  321.  
  322. //////////
  323. //
  324. // VRScript_ProcessScriptCommandLine
  325. // Process a script command line.
  326. //
  327. // Remember that this application is intended to illustrate how to integrate media with
  328. // QuickTime VR movies; it is not meant to provide a commercial-quality scripting language
  329. // and parser. You've been warned!
  330. //
  331. //////////
  332.  
  333. void VRScript_ProcessScriptCommandLine (WindowObject theWindowObject, char *theCommandLine)
  334. {
  335.     UInt32        myResID;
  336.     UInt32        myNodeID;
  337.     UInt32        myOptions;
  338.     UInt32        myUInt32;
  339.     UInt32        myEntryID;
  340.     UInt32        mySpriteID;
  341.     UInt32        myHotSpotID;
  342.     SInt32        myMaxTimes;
  343.     float        myPanAngle;
  344.     float        myTiltAngle;
  345.     float        myFOVAngle;
  346.     float        myMinAngle;
  347.     float        myMaxAngle;
  348.     float        myTempAngle;
  349.     float        myFloat;
  350.     char        myCommand[kMaxCmdWordLength];
  351.     char        myCmdLine[kMaxCmdLineLength];
  352.     char        myPathName[kMaxFileNameLength];
  353.     UInt32        myCode;                                // the command code for myCommand
  354.     
  355.     //////////
  356.     //
  357.     // do any necessary preprocessing on the command line
  358.     //
  359.     //////////
  360.     
  361.     // decode the string, if necessary;
  362.     // any line that begins with '@' is assumed to be encoded using a simple rotate-11 scheme
  363.     if (theCommandLine[0] == '@') {
  364.         theCommandLine++;                            // get rid of the '@'
  365.         VRScript_DecodeString(theCommandLine);        // decode the rest of the command
  366.     }
  367. #if ONLY_ENCODED_SCRIPTS
  368.     else {
  369.         if (gReadingScriptFile)
  370.             return;                                    // we allow only encoded scripts
  371.     }
  372. #endif
  373.  
  374.     // strip off any leading white space
  375.     while (isspace(theCommandLine[0]))
  376.         theCommandLine++;
  377.         
  378.     //////////
  379.     //
  380.     // filter out an otiose command line
  381.     //
  382.     //////////
  383.     
  384.     // ignore an empty command line
  385.     if (strlen(theCommandLine) == 0)
  386.         return;
  387.  
  388.     // any line that begins with '#' is a comment; ignore it
  389.     if (theCommandLine[0] == '#')
  390.         return;
  391.         
  392.     //////////
  393.     //
  394.     // extract the command word from the command line
  395.     //
  396.     //////////
  397.  
  398.     sscanf(theCommandLine, "%s ", myCommand);
  399.     if (strlen(myCommand) == 0)
  400.         return;
  401.         
  402.     //////////
  403.     //
  404.     // process the command word
  405.     //
  406.     //////////
  407.     
  408.     myCode = VRHash_GetCommandCode(myCommand);
  409.     switch (myCode) {
  410.         case kInvalidCommand:
  411.         case kOpenQTVRMovieFile:
  412.             break;
  413.             
  414.         case kReplaceMainMovie: {         // open the specified QuickTime movie in place of the current one
  415.             UInt32        myOverlayType;
  416.             UInt32        myNameType;
  417.             
  418.             sscanf(theCommandLine, "%*s %ld %ld %ld %s", &myOverlayType, &myNameType, &myOptions, myPathName);
  419.             VRScript_SetCurrentMovie(theWindowObject, myOverlayType, myNameType, myOptions, myPathName);
  420.             break;
  421.         }
  422.         
  423.         case kSetCurrentDirectory: {    // set the directory to search for content files
  424.         
  425.             // NOTE: as currently implemented, the "current directory" is set for the application, not for
  426.             // each open QTVR movie; this means that one QTVR movie can change the current directory and thus
  427.             // affect the search path of another open QTVR movie. This isn't optimal. It would be possible to
  428.             // fix this and attach a current directory to each open QTVR movie; however, the main use of this
  429.             // command is likely to be inside of the script file that's read when a QTVR movie is first opened.
  430.             // So I haven't bothered to do the work necessary to prevent current directory collisions. I might
  431.             // fix this at some point in the future.
  432.             
  433.             // NOTE: The pathname that is read from the command line must specify *a file* in the directory to
  434.             // be made current. The specified file does not actually need to exist, but the directory must.
  435.  
  436.             FSSpec        myFSSpec;
  437.             
  438.             sscanf(theCommandLine, "%*s %ld %s", &myOptions, myPathName);
  439.             VRScript_UnpackString(myPathName);
  440.             FSMakeFSSpec(0, 0L, c2pstr(myPathName), &myFSSpec);
  441.             VRScript_SetCurrentDirectory(&myFSSpec);
  442.             break;
  443.         }
  444.         
  445.         case kSetBarState:                 // show or hide the controller bar
  446.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  447.             VRScript_SetControllerBarState(theWindowObject, (Boolean)myUInt32, myOptions);
  448.             break;
  449.         
  450.         case kSetButtonState: {             // show or hide a button in the controller bar;
  451.             UInt32        myButton;        // or, enable or disable the display text in the bar
  452.             
  453.              // NOTE: the semantics of the custom controller button are reversed from the others: you need to
  454.              // ask VRScript to *hide* the button (myState == 0) if you want it to appear; I might fix this at
  455.              // some point in the future....
  456.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myButton, &myUInt32, &myOptions);
  457.             VRScript_SetControllerButtonState(theWindowObject, myButton, (Boolean)myUInt32, myOptions);
  458.             break;
  459.         }
  460.         
  461.         case kSetResizeState:             // enable or disable window resizing
  462.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  463.             VRScript_SetResizeState(theWindowObject, (Boolean)myUInt32, myOptions);
  464.             break;
  465.         
  466.         case kSetWindowSize: {             // set the current size of a movie window
  467.             UInt32                myHeight;
  468.             UInt32                myWidth;
  469.             Rect                myRect;
  470.             MovieController     myMC;
  471.             
  472.             if (theWindowObject == NULL)
  473.                 break;
  474.                 
  475.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myHeight, &myWidth, &myOptions);
  476.             myMC = (**theWindowObject).fController;
  477.             if (QTUtils_IsControllerBarVisible(myMC)) {
  478.                 MCGetControllerBoundsRect(myMC, &myRect);
  479.              } else {
  480.                 Movie    myMovie;
  481.                 
  482.                 myMovie = MCGetMovie(myMC);
  483.                 GetMovieBox(myMovie, &myRect);
  484.             }
  485.  
  486.             myRect.right = (short)myWidth;
  487.             myRect.bottom = (short)myHeight;
  488.             MCSetControllerBoundsRect(myMC, &myRect);
  489.             break;
  490.         }
  491.         
  492.         case kSetMaxWindowSize: {         // set the maximum size of a movie window
  493.             UInt32                myHeight;
  494.             UInt32                myWidth;
  495.             
  496.             if (theWindowObject == NULL)
  497.                 break;
  498.                 
  499.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myHeight, &myWidth, &myOptions);
  500.             gLimitRect.right = (short)myWidth;
  501.             gLimitRect.bottom = (short)myHeight;
  502.             VRScript_SetResizeState(theWindowObject, (**theWindowObject).fCanResizeWindow, myOptions);
  503.             break;
  504.         }
  505.         
  506.         case kReplaceCursor: {             // replace one cursor by another, or restore the original QTVR cursor
  507.             SInt32                myPrevID;
  508.             SInt32                myNewID;
  509.             QTVRCursorRecord    myCursorRec;
  510.             
  511.             if (theWindowObject == NULL)
  512.                 break;
  513.                 
  514.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myPrevID, &myNewID, &myOptions);
  515.  
  516.             myCursorRec.theType = (UInt16)myOptions;        // the type of cursor to replace
  517.             myCursorRec.rsrcID = (SInt16)myPrevID;            // the resource ID of cursor to replace
  518.             if (myOptions == kQTVRUseDefaultCursor) {
  519.                 myCursorRec.handle = NULL;
  520.             } else {
  521.                 myCursorRec.handle = (Handle)MacGetCursor((short)myNewID);
  522.                 if (myCursorRec.handle != NULL)
  523.                     DetachResource(myCursorRec.handle);
  524.             }
  525.             
  526.             QTVRReplaceCursor((**theWindowObject).fInstance, &myCursorRec);
  527.                 
  528.             // QTVRReplaceCursor makes a copy of the handle we pass it, so we can dispose of our handle;
  529.             // make sure not to dispose the handle if QTVR loaded it, however
  530.             if ((myCursorRec.handle != NULL) && (myOptions != kQTVRUseDefaultCursor))
  531.                 DisposeHandle(myCursorRec.handle);
  532.             
  533.             break;
  534.         }
  535.         
  536.         case kSetHotSpotIDCursors: {    // replace the triad of cursors for a hot spot specified by its ID; currently this works only for *undefined* hot spots
  537.             SInt32        myCurs1ID, myCurs2ID, myCurs3ID;    // resource IDs of the three replacement cursors
  538.  
  539.             if (theWindowObject == NULL)
  540.                 break;
  541.  
  542.             // read the command paramters    
  543.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %ld", &myNodeID, &myHotSpotID, &myCurs1ID, &myCurs2ID, &myCurs3ID, &myOptions);
  544.  
  545.             // enlist three ReplaceCursor calls for entering the hot spot: install new cursor triad
  546.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseUpOnUndefHS, myCurs3ID, kQTVRStdCursorType);
  547.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, 0L, kVRDoIt_Forever, kQTVRHotSpotEnter, myCmdLine);
  548.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseDownOnUndefHS, myCurs2ID, kQTVRStdCursorType);
  549.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, 0L, kVRDoIt_Forever, kQTVRHotSpotEnter, myCmdLine);
  550.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseOverUndefHS, myCurs1ID, kQTVRStdCursorType);
  551.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, 0L, kVRDoIt_Forever, kQTVRHotSpotEnter, myCmdLine);
  552.  
  553.             // enlist three ReplaceCursor calls for leaving the hot spot: reinstall original cursor triad
  554.             // NOTE: this prevents the new cursor from appearing on other hot spots of the same type, and
  555.             // also works around a bug in QTVR 2.0.0 and 2.0.1: replacing a cursor by itself disposes of 
  556.             // the cursor and eventually might lead to a crash.
  557.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseUpOnUndefHS, 0, kQTVRUseDefaultCursor);
  558.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, 0L, kVRDoIt_Forever, kQTVRHotSpotLeave, myCmdLine);
  559.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseDownOnUndefHS, 0, kQTVRUseDefaultCursor);
  560.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, 0L, kVRDoIt_Forever, kQTVRHotSpotLeave, myCmdLine);
  561.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseOverUndefHS, 0, kQTVRUseDefaultCursor);
  562.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, 0L, kVRDoIt_Forever, kQTVRHotSpotLeave, myCmdLine);
  563.  
  564.             // enlist three ReplaceCursor calls for leaving the node: reinstall original cursor triad
  565.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseUpOnUndefHS, 0, kQTVRUseDefaultCursor);
  566.             VRScript_EnlistNodeExitCommand(theWindowObject, myNodeID, kVRAnyNode, kVRDoIt_Forever, (UInt32)0, myCmdLine);
  567.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseDownOnUndefHS, 0, kQTVRUseDefaultCursor);
  568.             VRScript_EnlistNodeExitCommand(theWindowObject, myNodeID, kVRAnyNode, kVRDoIt_Forever, (UInt32)0, myCmdLine);
  569.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseOverUndefHS, 0, kQTVRUseDefaultCursor);
  570.             VRScript_EnlistNodeExitCommand(theWindowObject, myNodeID, kVRAnyNode, kVRDoIt_Forever, (UInt32)0, myCmdLine);
  571.  
  572.             break;
  573.         }
  574.         
  575.         case kSetHotSpotTypeCursors: {    // replace the triad of cursors for a hot spot specified by its type
  576.             char        myHotSpotType[kMaxOSTypeLength];
  577.             SInt32        myCurs1ID, myCurs2ID, myCurs3ID;    // resource IDs of the three replacement cursors
  578.             OSType        myType;
  579.  
  580.             if (theWindowObject == NULL)
  581.                 break;
  582.  
  583.             // read the command paramters    
  584.             sscanf(theCommandLine, "%*s %ld %s %ld %ld %ld %ld", &myNodeID, myHotSpotType, &myCurs1ID, &myCurs2ID, &myCurs3ID, &myOptions);
  585.             
  586.             // convert the string to an OSType
  587.             myType = VRScript_StringToOSType(myHotSpotType);
  588.             
  589.             // enlist three ReplaceCursor calls for entering the hot spot: install new cursor triad
  590.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseUpOnUndefHS, myCurs3ID, kQTVRStdCursorType);
  591.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, kVRDoIt_Forever, kQTVRHotSpotEnter, myCmdLine);
  592.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseDownOnUndefHS, myCurs2ID, kQTVRStdCursorType);
  593.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, kVRDoIt_Forever, kQTVRHotSpotEnter, myCmdLine);
  594.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseOverUndefHS, myCurs1ID, kQTVRStdCursorType);
  595.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, kVRDoIt_Forever, kQTVRHotSpotEnter, myCmdLine);
  596.  
  597.             // enlist three ReplaceCursor calls for leaving the hot spot: reinstall original cursor triad
  598.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseUpOnUndefHS, 0, kQTVRUseDefaultCursor);
  599.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, kVRDoIt_Forever, kQTVRHotSpotLeave, myCmdLine);
  600.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseDownOnUndefHS, 0, kQTVRUseDefaultCursor);
  601.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, kVRDoIt_Forever, kQTVRHotSpotLeave, myCmdLine);
  602.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseOverUndefHS, 0, kQTVRUseDefaultCursor);
  603.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, kVRDoIt_Forever, kQTVRHotSpotLeave, myCmdLine);
  604.  
  605.             // enlist three ReplaceCursor calls for leaving the node: reinstall original cursor triad
  606.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseUpOnUndefHS, 0, kQTVRUseDefaultCursor);
  607.             VRScript_EnlistNodeExitCommand(theWindowObject, myNodeID, kVRAnyNode, kVRDoIt_Forever, (UInt32)0, myCmdLine);
  608.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseDownOnUndefHS, 0, kQTVRUseDefaultCursor);
  609.             VRScript_EnlistNodeExitCommand(theWindowObject, myNodeID, kVRAnyNode, kVRDoIt_Forever, (UInt32)0, myCmdLine);
  610.             sprintf(myCmdLine, "ReplaceCursor %ld %ld %ld", kCursID_MouseOverUndefHS, 0, kQTVRUseDefaultCursor);
  611.             VRScript_EnlistNodeExitCommand(theWindowObject, myNodeID, kVRAnyNode, kVRDoIt_Forever, (UInt32)0, myCmdLine);
  612.  
  613.             break;
  614.         }
  615.         
  616.         case kGoToNodeID:                 // go to a node        
  617.             if (theWindowObject == NULL)
  618.                 break;
  619.                 
  620.             sscanf(theCommandLine, "%*s %ld %ld", &myNodeID, &myOptions);
  621.             QTVRGoToNodeID((**theWindowObject).fInstance, myNodeID);
  622.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  623.             break;
  624.         
  625.         case kShowDefaultView:             // display the default view of the current node        
  626.             if (theWindowObject == NULL)
  627.                 break;
  628.                 
  629.             QTVRShowDefaultView((**theWindowObject).fInstance);
  630.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  631.             break;
  632.         
  633.         case kOpenResourceFile:             // open the specified resource file
  634.             sscanf(theCommandLine, "%*s %ld %s", &myOptions, myPathName);
  635.             VRScript_UnpackString(myPathName);
  636.             VRScript_OpenResourceFile(theWindowObject, myOptions, myPathName);
  637.             break;
  638.         
  639.         case kSetCorrection:            // set the imaging correction mode
  640.             if (theWindowObject == NULL)
  641.                 break;
  642.                 
  643.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  644.             QTVRSetImagingProperty((**theWindowObject).fInstance, (QTVRImagingMode)myOptions, kQTVRImagingCorrection, myUInt32);
  645.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  646.             break;
  647.         
  648.         case kSetQuality:                // set the image quality
  649.             if (theWindowObject == NULL)
  650.                 break;
  651.                 
  652.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  653.             QTVRSetImagingProperty((**theWindowObject).fInstance, (QTVRImagingMode)myOptions, kQTVRImagingQuality, myUInt32);
  654.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  655.             break;
  656.         
  657.         case kSetSwingSpeed:             // set the speed of swing transitions
  658.             if (theWindowObject == NULL)
  659.                 break;
  660.                 
  661.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  662.             QTVRSetTransitionProperty((**theWindowObject).fInstance, kQTVRTransitionSwing, kQTVRTransitionSpeed, myUInt32);
  663.             break;
  664.         
  665.         case kSetSwingDirection:         // set the direction of swing transitions
  666.             if (theWindowObject == NULL)
  667.                 break;
  668.                 
  669.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  670.             QTVRSetTransitionProperty((**theWindowObject).fInstance, kQTVRTransitionSwing, kQTVRTransitionDirection, myUInt32);
  671.             break;
  672.         
  673.         case kSetSwingState:            // enable or disable swing transitions
  674.             if (theWindowObject == NULL)
  675.                 break;
  676.                 
  677.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  678.             QTVREnableTransition((**theWindowObject).fInstance, kQTVRTransitionSwing, (Boolean)myUInt32);
  679.             break;
  680.         
  681.         case kSetPanAngle:                 // set the pan angle
  682.             if (theWindowObject == NULL)
  683.                 break;
  684.                 
  685.             sscanf(theCommandLine, "%*s %f %ld", &myPanAngle, &myOptions);
  686.             myPanAngle = QTVRUtils_DegreesToRadians(myPanAngle);
  687.             
  688.             if (myOptions == kVRValue_Relative) {
  689.                 myTempAngle = QTVRGetPanAngle((**theWindowObject).fInstance);
  690.                 myPanAngle += myTempAngle;
  691.             }
  692.             
  693.             QTVRSetPanAngle((**theWindowObject).fInstance, myPanAngle);
  694.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  695.             break;
  696.         
  697.         case kSetTiltAngle:                // set the tilt angle
  698.             if (theWindowObject == NULL)
  699.                 break;
  700.                 
  701.             sscanf(theCommandLine, "%*s %f %ld", &myTiltAngle, &myOptions);
  702.             myTiltAngle = QTVRUtils_DegreesToRadians(myTiltAngle);
  703.             
  704.             if (myOptions == kVRValue_Relative) {
  705.                 myTempAngle = QTVRGetTiltAngle((**theWindowObject).fInstance);
  706.                 myTiltAngle += myTempAngle;
  707.             }
  708.             
  709.             QTVRSetTiltAngle((**theWindowObject).fInstance, myTiltAngle);
  710.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  711.             break;
  712.         
  713.         case kSetPanTiltZoom:             // set the pan, tilt, and zoom angles
  714.             if (theWindowObject == NULL)
  715.                 break;
  716.                 
  717.             sscanf(theCommandLine, "%*s %f %f %f %ld %ld", &myPanAngle, &myTiltAngle, &myFOVAngle, &myUInt32, &myOptions);
  718.             myPanAngle = QTVRUtils_DegreesToRadians(myPanAngle);
  719.             myTiltAngle = QTVRUtils_DegreesToRadians(myTiltAngle);
  720.             myFOVAngle = QTVRUtils_DegreesToRadians(myFOVAngle);
  721.             
  722.             if (myOptions == kVRValue_Relative) {
  723.                 myTempAngle = QTVRGetPanAngle((**theWindowObject).fInstance);
  724.                 myPanAngle += myTempAngle;
  725.                 myTempAngle = QTVRGetTiltAngle((**theWindowObject).fInstance);
  726.                 myTiltAngle += myTempAngle;
  727.                 myTempAngle = QTVRGetFieldOfView((**theWindowObject).fInstance);
  728.                 myFOVAngle += myTempAngle;
  729.             }
  730.             
  731.             // enable swing transitions, if requested by myMode parameter
  732.             if ((myUInt32 == kVRTransition_Swing) || (myUInt32 == kVRTransition_SwingWait))
  733.                 QTVREnableTransition((**theWindowObject).fInstance, kQTVRTransitionSwing, true);
  734.             
  735.             // set the desired FOV, pan, and tilt angles
  736.             QTVRSetFieldOfView((**theWindowObject).fInstance, myFOVAngle);
  737.             QTVRSetPanAngle((**theWindowObject).fInstance, myPanAngle);
  738.             QTVRSetTiltAngle((**theWindowObject).fInstance, myTiltAngle);
  739.  
  740.             // update the screen
  741.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  742.  
  743.             // if a blocking swing is requested, "spin our wheels" until we get (close to) to the destination angles
  744.             if (myUInt32 == kVRTransition_SwingWait)
  745.                 while (!VRScript_FloatsAreEqual(myPanAngle, QTVRGetPanAngle((**theWindowObject).fInstance), kRadianTolerance) ||
  746.                        !VRScript_FloatsAreEqual(myTiltAngle, QTVRGetTiltAngle((**theWindowObject).fInstance), kRadianTolerance) ||
  747.                        !VRScript_FloatsAreEqual(myFOVAngle, QTVRGetFieldOfView((**theWindowObject).fInstance), kRadianTolerance)) {
  748.                        
  749.                     QTVRSetFieldOfView((**theWindowObject).fInstance, myFOVAngle);
  750.                     QTVRSetPanAngle((**theWindowObject).fInstance, myPanAngle);
  751.                     QTVRSetTiltAngle((**theWindowObject).fInstance, myTiltAngle);
  752.                     
  753.                     DoIdle((**theWindowObject).fWindow); 
  754.                     MCIdle((**theWindowObject).fController); 
  755.                 }
  756.  
  757.             // disable swing transitions, if previously enabled
  758.             if ((myUInt32 == kVRTransition_Swing) || (myUInt32 == kVRTransition_SwingWait))
  759.                 QTVREnableTransition((**theWindowObject).fInstance, kQTVRTransitionSwing, false);
  760.                 
  761.             break;
  762.         
  763.         case kSetFieldOfView:             // set the field of view
  764.             if (theWindowObject == NULL)
  765.                 break;
  766.                 
  767.             sscanf(theCommandLine, "%*s %f %ld", &myFOVAngle, &myOptions);
  768.             myFOVAngle = QTVRUtils_DegreesToRadians(myFOVAngle);
  769.             
  770.             if (myOptions == kVRValue_Relative) {
  771.                 myTempAngle = QTVRGetFieldOfView((**theWindowObject).fInstance);
  772.                 myFOVAngle += myTempAngle;
  773.             }
  774.             
  775.             QTVRSetFieldOfView((**theWindowObject).fInstance, myFOVAngle);
  776.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  777.             break;
  778.         
  779.         case kSetViewCenter: {             // set the view center of an object node
  780.             QTVRFloatPoint        myPoint;
  781.             
  782.             if (theWindowObject == NULL)
  783.                 break;
  784.                 
  785.             sscanf(theCommandLine, "%*s %f %f %ld", &myPoint.x, &myPoint.y, &myOptions);
  786.             QTVRSetViewCenter((**theWindowObject).fInstance, &myPoint);
  787.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  788.             break;
  789.         }
  790.         
  791.         case kSetPanLimits:                 // set the current pan angle constraints
  792.             sscanf(theCommandLine, "%*s %f %f %ld", &myMinAngle, &myMaxAngle, &myOptions);
  793.             VRScript_SetAngleConstraints(theWindowObject, kQTVRPan, myMinAngle, myMaxAngle, myOptions);
  794.             break;
  795.         
  796.         case kSetTiltLimits:             // set the current tilt angle constraints
  797.             sscanf(theCommandLine, "%*s %f %f %ld", &myMinAngle, &myMaxAngle, &myOptions);
  798.             VRScript_SetAngleConstraints(theWindowObject, kQTVRTilt, myMinAngle, myMaxAngle, myOptions);
  799.             break;
  800.         
  801.         case kSetZoomLimits:             // set the current zoom angle constraints
  802.             sscanf(theCommandLine, "%*s %f %f %ld", &myMinAngle, &myMaxAngle, &myOptions);
  803.             VRScript_SetAngleConstraints(theWindowObject, kQTVRFieldOfView, myMinAngle, myMaxAngle, myOptions);
  804.             break;
  805.         
  806.         case kSetHotSpotState: {         // enable or disable a hot spot;
  807.             UInt32        myState;        // there's no easy way to get the current state of a hot spot, so we don't support toggling
  808.  
  809.             if (theWindowObject == NULL)
  810.                 break;
  811.                 
  812.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myHotSpotID, &myState, &myOptions);
  813.             QTVREnableHotSpot((**theWindowObject).fInstance, myOptions, myHotSpotID, (Boolean)myState);
  814.             
  815.             // we need to update, because the hot spot regions might currently be showing
  816.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  817.  
  818.             break;
  819.         }
  820.         
  821.         case kSetTranslateState:         // enable or disable object translation
  822.             if (theWindowObject == NULL)
  823.                 break;
  824.                 
  825.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  826.             QTVRSetInteractionProperty((**theWindowObject).fInstance, kQTVRInteractionTranslateOnMouseDown, (void *)myUInt32);
  827.             break;
  828.         
  829.         case kSetClickRadius: {             // set the radius within which clicks occur
  830.             UInt16        myRadius;
  831.  
  832.             if (theWindowObject == NULL)
  833.                 break;
  834.                 
  835.             sscanf(theCommandLine, "%*s %ld %ld", &myRadius, &myOptions);
  836.             QTVRSetInteractionProperty((**theWindowObject).fInstance, kQTVRInteractionMouseClickHysteresis, (void *)myRadius);
  837.             break;
  838.         }
  839.         
  840.         case kSetClickTimeout:             // set the timeout for clicks
  841.             if (theWindowObject == NULL)
  842.                 break;
  843.                 
  844.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  845.             QTVRSetInteractionProperty((**theWindowObject).fInstance, kQTVRInteractionMouseClickTimeout, (void *)myUInt32);
  846.             break;
  847.         
  848.         case kSetPanTiltSpeed:             // set the pan and tilt speed
  849.             if (theWindowObject == NULL)
  850.                 break;
  851.                 
  852.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  853.             QTVRSetInteractionProperty((**theWindowObject).fInstance, kQTVRInteractionPanTiltSpeed, (void *)myUInt32);
  854.             break;
  855.         
  856.         case kSetZoomSpeed:                 // set the zoom speed
  857.             if (theWindowObject == NULL)
  858.                 break;
  859.                 
  860.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  861.             QTVRSetInteractionProperty((**theWindowObject).fInstance, kQTVRInteractionZoomSpeed, (void *)myUInt32);
  862.             break;
  863.         
  864.         case kSetMouseScale:             // set the mouse-motion scale
  865.             if (theWindowObject == NULL)
  866.                 break;
  867.                 
  868.             sscanf(theCommandLine, "%*s %f %ld", &myFloat, &myOptions);
  869.             myFloat = QTVRUtils_DegreesToRadians(myFloat);
  870.             QTVRSetInteractionProperty((**theWindowObject).fInstance, kQTVRInteractionMouseMotionScale, &myFloat);
  871.             break;
  872.         
  873.         case kSetFrameRate:                 // set the frame rate of an object node
  874.             if (theWindowObject == NULL)
  875.                 break;
  876.                 
  877.             sscanf(theCommandLine, "%*s %f %ld", &myFloat, &myOptions);
  878.  
  879.             if (myOptions == kVRValue_Relative)
  880.                 myFloat += QTVRGetFrameRate((**theWindowObject).fInstance);
  881.             
  882.             QTVRSetFrameRate((**theWindowObject).fInstance, myFloat);
  883.             break;
  884.         
  885.         case kSetViewRate:                 // set the view rate of an object node
  886.             if (theWindowObject == NULL)
  887.                 break;
  888.                 
  889.             sscanf(theCommandLine, "%*s %f %ld", &myFloat, &myOptions);
  890.             
  891.             if (myOptions == kVRValue_Relative)
  892.                 myFloat += QTVRGetViewRate((**theWindowObject).fInstance);
  893.             
  894.             QTVRSetViewRate((**theWindowObject).fInstance, myFloat);
  895.             break;
  896.         
  897.         case kSetViewTime: {             // set the current view time of an object node
  898.             TimeValue    myTime;
  899.  
  900.             if (theWindowObject == NULL)
  901.                 break;
  902.                 
  903.             sscanf(theCommandLine, "%*s %f %ld", &myTime, &myOptions);
  904.             
  905.             if (myOptions == kVRValue_Relative)
  906.                 myTime += QTVRGetViewCurrentTime((**theWindowObject).fInstance);
  907.             
  908.             QTVRSetViewCurrentTime((**theWindowObject).fInstance, myTime);
  909.             break;
  910.         }
  911.         
  912.         case kSetViewState: {             // set the current view state of an object node
  913.             UInt32        myType;
  914.             UInt32        myState;
  915.  
  916.             if (theWindowObject == NULL)
  917.                 break;
  918.                 
  919.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myType, &myState, &myOptions);
  920.             QTVRSetViewState((**theWindowObject).fInstance, (QTVRViewStateType)myType, (UInt16)myState);
  921.             break;
  922.         }
  923.         
  924.         case kSetAnimationState: {         // set the animation state of an object node
  925.             UInt32        mySetting;
  926.             UInt32        myState;
  927.  
  928.             if (theWindowObject == NULL)
  929.                 break;
  930.                 
  931.             sscanf(theCommandLine, "%*s %ld %ld %ld", &mySetting, &myState, &myOptions);
  932.             QTVRSetAnimationSetting((**theWindowObject).fInstance, (QTVRObjectAnimationSetting)mySetting, (Boolean)myState);
  933.             break;
  934.         }
  935.         
  936.         case kSetControlState: {         // set the control state of an object node
  937.             UInt32        mySetting;
  938.             UInt32        myState;
  939.  
  940.             if (theWindowObject == NULL)
  941.                 break;
  942.                 
  943.             sscanf(theCommandLine, "%*s %ld %ld %ld", &mySetting, &myState, &myOptions);
  944.             QTVRSetControlSetting((**theWindowObject).fInstance, (QTVRControlSetting)mySetting, (Boolean)myState);
  945.             break;
  946.         }
  947.         
  948.         case kSetFrameAnimState:         // enable or disable frame animation in an object node
  949.             if (theWindowObject == NULL)
  950.                 break;
  951.                 
  952.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  953.             QTVREnableFrameAnimation((**theWindowObject).fInstance, (Boolean)myUInt32);
  954.             break;
  955.         
  956.         case kSetViewAnimState:             // enable or disable view animation in an object node
  957.             if (theWindowObject == NULL)
  958.                 break;
  959.                 
  960.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  961.             QTVREnableViewAnimation((**theWindowObject).fInstance, (Boolean)myUInt32);
  962.             break;
  963.         
  964.         case kSetQTVRVisState:             // enable or disable QTVR movie visibility
  965.             if (theWindowObject == NULL)
  966.                 break;
  967.                 
  968.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  969.             QTVRSetVisible((**theWindowObject).fInstance, (Boolean)myUInt32);
  970.             break;
  971.         
  972.         case kSetCachePrefs: {             // set the back buffer resolution, depth, and size
  973.             SInt32        myResolution;
  974.             SInt32        myDepth;
  975.             SInt32        mySize;
  976.  
  977.             if (theWindowObject == NULL)
  978.                 break;
  979.                 
  980.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld", &myResolution, &myDepth, &mySize, &myOptions);
  981.             QTVRSetBackBufferPrefs((**theWindowObject).fInstance, kQTVRUseMovieGeometry, (UInt16)myResolution, (SInt16)myDepth, (SInt16)mySize);
  982.             break;
  983.         }
  984.         
  985.         case kSetMovieVolume:             // set the volume of a QTVR sound track
  986.             if (theWindowObject == NULL)
  987.                 break;
  988.                 
  989.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  990.             SetMovieVolume((**theWindowObject).fMovie, (short)myUInt32);
  991.             break;
  992.         
  993.         case kSetSoundVolume: {             // set the volume of a sound
  994.             UInt32                myVolume;
  995.             VRScriptSoundPtr    mySoundPtr;
  996.             VRScriptMoviePtr    myMoviePtr;
  997.  
  998.             if (theWindowObject == NULL)
  999.                 break;
  1000.                 
  1001.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myVolume, &myOptions);
  1002.             
  1003.             // is it a sound resource?
  1004.             mySoundPtr = (VRScriptSoundPtr)VRScript_GetObjectByEntryID(theWindowObject, kVREntry_Sound, myEntryID);
  1005.             if (mySoundPtr != NULL) {
  1006.                 VRSound_SetVolume(mySoundPtr->fChannel, (unsigned short)myVolume, (unsigned short)myVolume);
  1007.                 break;
  1008.             }
  1009.             
  1010.             // is it a movie sound track?
  1011.             myMoviePtr = (VRScriptMoviePtr)VRScript_GetObjectByEntryID(theWindowObject, kVREntry_QTMovie, myEntryID);
  1012.             if (myMoviePtr != NULL)
  1013.                 SetMovieVolume(myMoviePtr->fMovie, (short)myVolume);
  1014.  
  1015.             break;
  1016.         }
  1017.         
  1018.         case kSetSoundBalance: {         // set the balance of a sound
  1019.             UInt32                myLeftPct;
  1020.             UInt32                myRightPct;
  1021.             VRScriptSoundPtr    mySoundPtr;
  1022.             VRScriptMoviePtr    myMoviePtr;
  1023.             unsigned short        myLeftVol, myRightVol;
  1024.  
  1025.             if (theWindowObject == NULL)
  1026.                 break;
  1027.                 
  1028.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld", &myEntryID, &myLeftPct, &myRightPct, &myOptions);
  1029.             
  1030.             // is it a sound resource?
  1031.             mySoundPtr = (VRScriptSoundPtr)VRScript_GetObjectByEntryID(theWindowObject, kVREntry_Sound, myEntryID);
  1032.             if (mySoundPtr != NULL) {
  1033.                 VRSound_GetVolume(mySoundPtr->fChannel, &myLeftVol, &myRightVol);
  1034.                 VRSound_SetVolume(mySoundPtr->fChannel, myLeftVol * (myLeftPct / 100), myRightVol * (myRightPct / 100));
  1035.                 break;
  1036.             }
  1037.             
  1038.             // is it a movie sound track?
  1039.             myMoviePtr = (VRScriptMoviePtr)VRScript_GetObjectByEntryID(theWindowObject, kVREntry_QTMovie, myEntryID);
  1040.             if (myMoviePtr != NULL) {
  1041.                 short            myValue;
  1042.                 
  1043.                 myValue = (((float)myRightPct / 100) * kQTMaxSoundVolume) - (((float)myLeftPct / 100) * kQTMaxSoundVolume);
  1044.                 MediaSetSoundBalance(myMoviePtr->fMediaHandler, myValue);
  1045.             }
  1046.             
  1047.             break;
  1048.         }
  1049.         
  1050.         case kPlaySceneSound: {            // play a movie-wide ambient sound asynchronously
  1051.              UInt32        myMode;
  1052.              UInt32        myFade;
  1053.  
  1054.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld", &myResID, &myEntryID, &myMode, &myFade, &myOptions);
  1055.             VRSound_PlaySound(theWindowObject, kVRAnyNode, myResID, myEntryID, 1.0, 1.0, 1.0, 1.0, kSSpSourceMode_Ambient, myMode, myFade, myOptions);
  1056.             break;
  1057.         }
  1058.         
  1059.         case kPlaySceneQTMidi: {        // play a movie-wide ambient QuickTime sound-only file asynchronously
  1060.             UInt32        myMode;
  1061.              UInt32        myFade;
  1062.              UInt32        myIsLocal;
  1063.             float        myX, myY, myZ;
  1064.             float        myProjAngle;
  1065.         
  1066.             sscanf(theCommandLine, "%*s %ld %ld %f %f %f %f %ld %ld %ld %s", &myEntryID, &myIsLocal, &myX, &myY, &myZ, &myProjAngle, &myMode, &myFade, &myOptions, myPathName);
  1067.             myProjAngle = QTVRUtils_DegreesToRadians(myProjAngle);
  1068.             VRMoov_PlayMovie(theWindowObject, kVRAnyNode, myEntryID, QTVRUtils_Point3DToPanAngle(myX, myY, myZ), QTVRUtils_Point3DToTiltAngle(myX, myY, myZ), 0.0, 0.0, 0.0, 0.0, 0.0, false, false, false, false, myIsLocal, myIsLocal, myProjAngle, myMode, myOptions, myPathName);
  1069.             break;
  1070.         }
  1071.         
  1072.         case kPlayNodeQTMidi: {             // play a QuickTime MIDI file in a node
  1073.             UInt32        myMode;
  1074.             UInt32        myFade;
  1075.              UInt32        myIsLocal;
  1076.             float        myX, myY, myZ;
  1077.             float        myProjAngle;
  1078.             
  1079.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %f %f %f %f %ld %ld %ld %s", &myNodeID, &myEntryID, &myMaxTimes, &myIsLocal, &myX, &myY, &myZ, &myProjAngle, &myMode, &myFade, &myOptions, myPathName);
  1080.             sprintf(myCmdLine, "PlayQTMidi %ld %ld %f %f %f %f %ld %ld %ld %s", myEntryID, myIsLocal, myX, myY, myZ, myProjAngle, myMode, myFade, myOptions, myPathName);
  1081.             VRScript_EnlistNodeEntryCommand(theWindowObject, myNodeID, myMaxTimes, 0, myCmdLine);
  1082.             break;
  1083.         }
  1084.         
  1085.         case kPlayNodeSound: {             // play a sound in a node
  1086.             UInt32        myMode;
  1087.             UInt32        myFade;
  1088.  
  1089.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %ld", &myResID, &myNodeID, &myEntryID, &myMaxTimes, &myMode, &myFade, &myOptions);
  1090.             sprintf(myCmdLine, "PlaySndResource %ld %ld %ld %ld %ld", myResID, myEntryID, myMode, myFade, myOptions);
  1091.             VRScript_EnlistNodeEntryCommand(theWindowObject, myNodeID, myMaxTimes, 0, myCmdLine);
  1092.             break;
  1093.         }
  1094.         
  1095.         case kPlayNode3DSound: {         // play a 3D sound in a node
  1096.             float        myX, myY, myZ;
  1097.             float        myProjAngle;
  1098.             UInt32        mySourceMode;
  1099.             UInt32        myMode;
  1100.             UInt32        myFade;
  1101.  
  1102.             sscanf(theCommandLine, "%*s %ld %ld %ld %f %f %f %f %ld %ld %ld %ld %ld", &myResID, &myNodeID, &myEntryID, &myX, &myY, &myZ, &myProjAngle, &mySourceMode, &myMaxTimes, &myMode, &myFade, &myOptions);
  1103.             sprintf(myCmdLine, "Play3DSndResource %ld %ld %f %f %f %f %ld %ld %ld %ld", myResID, myEntryID, myX, myY, myZ, myProjAngle, mySourceMode, myMode, myFade, myOptions);
  1104.             VRScript_EnlistNodeEntryCommand(theWindowObject, myNodeID, myMaxTimes, 0, myCmdLine);
  1105.             break;
  1106.         }
  1107.         
  1108.         case kHotSpotQTMidi: {             // play a QuickTime MIDI file when a hot spot is clicked
  1109.             UInt32        myMode;
  1110.             UInt32        myFade;
  1111.              UInt32        myIsLocal;
  1112.             float        myX, myY, myZ;
  1113.             float        myProjAngle;
  1114.             
  1115.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %f %f %f %f %ld %ld %ld %s", &myNodeID, &myHotSpotID, &myEntryID, &myMaxTimes, &myIsLocal, &myX, &myY, &myZ, &myProjAngle, &myMode, &myFade, &myOptions, myPathName);
  1116.             sprintf(myCmdLine, "PlayQTMidi %ld %ld %f %f %f %f %ld %ld %ld %s", myEntryID, myIsLocal, myX, myY, myZ, myProjAngle, myMode, myFade, myOptions, myPathName);
  1117.             VRScript_EnlistClickHSCommand(theWindowObject, myNodeID, myHotSpotID, (OSType)0, myMaxTimes, 0, myCmdLine);
  1118.             break;
  1119.         }
  1120.         
  1121.         case kHotSpotSound: {             // play a sound when a hot spot is clicked
  1122.             UInt32        myMode;
  1123.             UInt32        myFade;
  1124.  
  1125.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %ld %ld %ld", &myResID, &myNodeID, &myHotSpotID, &myEntryID, &myMaxTimes, &myMode, &myFade, &myOptions);
  1126.             sprintf(myCmdLine, "PlaySndResource %ld %ld %ld %ld %ld", myResID, myEntryID, myMode, myFade, myOptions);
  1127.             VRScript_EnlistClickHSCommand(theWindowObject, myNodeID, myHotSpotID, (OSType)0, myMaxTimes, 0, myCmdLine);
  1128.             break;
  1129.         }
  1130.         
  1131.         case kHotSpot3DSound: {             // play a 3D sound when a hot spot is clicked
  1132.             float        myX, myY, myZ;
  1133.             float        myProjAngle;
  1134.             UInt32        mySourceMode;
  1135.             UInt32        myMode;
  1136.             UInt32        myFade;
  1137.  
  1138.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %f %f %f %f %ld %ld %ld %ld %ld", &myResID, &myNodeID, &myHotSpotID, &myEntryID, &myX, &myY, &myZ, &myProjAngle, &mySourceMode, &myMaxTimes, &myMode, &myFade, &myOptions);
  1139.             sprintf(myCmdLine, "Play3DSndResource %ld %ld %f %f %f %f %ld %ld %ld %ld", myResID, myEntryID, myX, myY, myZ, myProjAngle, mySourceMode, myMode, myFade, myOptions);
  1140.             VRScript_EnlistClickHSCommand(theWindowObject, myNodeID, myHotSpotID, (OSType)0, myMaxTimes, 0, myCmdLine);
  1141.             break;
  1142.         }
  1143.         
  1144.         case kHotSpotMovie: {             // play a movie when a hot spot is clicked
  1145.              float        myScale;
  1146.              float        myWidth;
  1147.              UInt32        myKeyRed;
  1148.              UInt32        myKeyGreen;
  1149.              UInt32        myKeyBlue;
  1150.             UInt32        myUseBuffer;
  1151.             UInt32        myUseCenter;
  1152.             UInt32        myUseKey;
  1153.             UInt32        myUseHide;
  1154.             UInt32        myUseDir;
  1155.             UInt32        myRotate;
  1156.              float        myVolAngle;
  1157.             UInt32        myMode;
  1158.  
  1159.             sscanf(theCommandLine, "%*s %ld %ld %ld %f %f %f %f %ld %ld %ld %ld %ld %ld %ld %ld %ld %f %ld %ld %ld %s", 
  1160.                     &myEntryID, 
  1161.                     &myNodeID, 
  1162.                     &myHotSpotID, 
  1163.                     &myPanAngle,
  1164.                     &myTiltAngle,
  1165.                     &myScale, 
  1166.                     &myWidth, 
  1167.                     &myKeyRed, 
  1168.                     &myKeyGreen, 
  1169.                     &myKeyBlue, 
  1170.                     &myUseBuffer,
  1171.                     &myUseCenter,
  1172.                     &myUseKey,
  1173.                     &myUseHide,
  1174.                     &myUseDir,
  1175.                     &myRotate,
  1176.                     &myVolAngle,
  1177.                     &myMaxTimes,
  1178.                     &myMode,
  1179.                     &myOptions,
  1180.                     myPathName);
  1181.                 
  1182.             sprintf(myCmdLine, "PlayMovie %ld %f %f %f %f %ld %ld %ld %ld %ld %ld %ld %ld %ld %f %ld %ld %s",
  1183.                     myEntryID,
  1184.                     myPanAngle,
  1185.                     myTiltAngle,
  1186.                     myScale, 
  1187.                     myWidth, 
  1188.                     myKeyRed, 
  1189.                     myKeyGreen, 
  1190.                     myKeyBlue, 
  1191.                     (Boolean)myUseBuffer,
  1192.                     (Boolean)myUseCenter,
  1193.                     (Boolean)myUseKey,
  1194.                     (Boolean)myUseHide,
  1195.                     (Boolean)myUseDir,
  1196.                     (Boolean)myRotate,
  1197.                     myVolAngle,
  1198.                     myMode,
  1199.                     myOptions,
  1200.                     myPathName);
  1201.  
  1202.             VRScript_EnlistClickHSCommand(theWindowObject, myNodeID, myHotSpotID, (OSType)0, myMaxTimes, 0, myCmdLine);
  1203.             break;
  1204.         }
  1205.         
  1206.         case kTriggerHotSpot:             // trigger a particular hot spot
  1207.             if (theWindowObject == NULL)
  1208.                 break;
  1209.                 
  1210.             sscanf(theCommandLine, "%*s %ld %ld", &myUInt32, &myOptions);
  1211.             QTVRTriggerHotSpot((**theWindowObject).fInstance, myUInt32, 0, 0);
  1212.             break;
  1213.         
  1214.         case kPlayQTMidi: {                // play a QuickTime sound-only file asynchronously, or stop a file from playing
  1215.             UInt32        myMode;
  1216.              UInt32        myFade;
  1217.              UInt32        myIsLocal;
  1218.             float        myX, myY, myZ;
  1219.             float        myProjAngle;
  1220.         
  1221.             if (theWindowObject == NULL)
  1222.                 break;
  1223.                 
  1224.             myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  1225.  
  1226.             sscanf(theCommandLine, "%*s %ld %ld %f %f %f %f %ld %ld %ld %s", &myEntryID, &myIsLocal, &myX, &myY, &myZ, &myProjAngle, &myMode, &myFade, &myOptions, myPathName);
  1227.             myProjAngle = QTVRUtils_DegreesToRadians(myProjAngle);
  1228.             VRMoov_PlayMovie(theWindowObject, myNodeID, myEntryID, QTVRUtils_Point3DToPanAngle(myX, myY, myZ), QTVRUtils_Point3DToTiltAngle(myX, myY, myZ), 0.0, 0.0, 0.0, 0.0, 0.0, false, false, false, false, myIsLocal, myIsLocal, myProjAngle, myMode, myOptions, myPathName);
  1229.             break;
  1230.         }
  1231.         
  1232.         case kPlaySndResource: {        // play a sound resource ambiently, or stop an ambient sound resource from playing
  1233.              UInt32        myMode;
  1234.              UInt32        myFade;
  1235.  
  1236.             if (theWindowObject == NULL)
  1237.                 break;
  1238.             
  1239.             myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  1240.             
  1241.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld", &myResID, &myEntryID, &myMode, &myFade, &myOptions);
  1242.             VRSound_PlaySound(theWindowObject, myNodeID, myResID, myEntryID, 1.0, 1.0, 1.0, 1.0, kSSpSourceMode_Ambient, myMode, myFade, myOptions);
  1243.             break;
  1244.         }
  1245.         
  1246.         case kPlaySoundFile: {            // play a sound file ambiently, or stop an ambient sound file from playing
  1247.              UInt32        myMode;
  1248.              UInt32        myFade;
  1249.             short        myRefNum;
  1250.             short        myResID;
  1251.  
  1252.             if (theWindowObject == NULL)
  1253.                 break;
  1254.             
  1255.             myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  1256.             
  1257.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %s", &myEntryID, &myMode, &myFade, &myOptions, myPathName);
  1258.             
  1259.             // a sound file (of type 'sfil') is a resource file that contains one 'snd ' resource,
  1260.             // so open the resource file and get the resource ID; then call VRSound_PlaySound.
  1261.             myRefNum = VRScript_OpenResourceFile(theWindowObject, 0, myPathName);
  1262.             myResID = VRSound_GetSndResourceID(myRefNum);
  1263.             VRSound_PlaySound(theWindowObject, myNodeID, myResID, myEntryID, 1.0, 1.0, 1.0, 1.0, kSSpSourceMode_Ambient, myMode, myFade, myOptions);
  1264.             break;
  1265.         }
  1266.         
  1267.         case kPlay3DSndResource: {        // play a sound file localized, or stop an ambient sound file from playing
  1268.             float        myX, myY, myZ;
  1269.             float        myProjAngle;
  1270.             UInt32        mySourceMode;
  1271.              UInt32        myMode;
  1272.             UInt32        myFade;
  1273.  
  1274.             if (theWindowObject == NULL)
  1275.                 break;
  1276.  
  1277.             myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  1278.             
  1279.             sscanf(theCommandLine, "%*s %ld %ld %f %f %f %f %ld %ld %ld %ld", &myResID, &myEntryID, &myX, &myY, &myZ, &myProjAngle, &mySourceMode, &myMode, &myFade, &myOptions);
  1280.             myProjAngle = QTVRUtils_DegreesToRadians(myProjAngle);
  1281.             VRSound_PlaySound(theWindowObject, myNodeID, myResID, myEntryID, myX, myY, myZ, myProjAngle, mySourceMode, myMode, myFade, myOptions);
  1282.             break;
  1283.         }
  1284.         
  1285.         case kPlay3DSndResourceAngle: {    // play a localized sound, specified using angles
  1286.             TQ3Point3D    myPoint;
  1287.             float        myDistance;
  1288.             float        myProjAngle;
  1289.             UInt32        mySourceMode;
  1290.             UInt32        myMode;
  1291.             UInt32        myFade;
  1292.         
  1293.             if (theWindowObject == NULL)
  1294.                 break;
  1295.  
  1296.             myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  1297.             
  1298.             sscanf(theCommandLine, "%*s %ld %ld %f %f %f %f %ld %ld %ld", &myResID, &myEntryID, &myPanAngle, &myTiltAngle, &myDistance, &myProjAngle, &mySourceMode, &myMode, &myFade, &myOptions);
  1299.             myPanAngle = QTVRUtils_DegreesToRadians(myPanAngle);
  1300.             myTiltAngle = QTVRUtils_DegreesToRadians(myTiltAngle);
  1301.             myProjAngle = QTVRUtils_DegreesToRadians(myProjAngle);
  1302.  
  1303.             myPoint.x = -sin(myPanAngle) * cos(myTiltAngle) * (myDistance);
  1304.             myPoint.y = sin(myTiltAngle) * (myDistance);
  1305.             myPoint.z = -cos(myPanAngle) * cos(myTiltAngle) * (myDistance);
  1306.  
  1307.             VRSound_PlaySound(theWindowObject, myNodeID, myResID, myEntryID, myPoint.x, myPoint.y, myPoint.z, myProjAngle, mySourceMode, myMode, myFade, myOptions);
  1308.             break;
  1309.         }
  1310.         
  1311.         case kShowPicture: {            // overlay a picture (in the front buffer)
  1312.             UInt32        myHeight;
  1313.             UInt32        myWidth;
  1314.             UInt32        myPegSides;
  1315.             UInt32        myOffset;
  1316.  
  1317.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %ld %ld", &myResID, &myEntryID, &myHeight, &myWidth, &myPegSides, &myOffset, &myOptions);
  1318.             VRPicture_ShowPicture(theWindowObject, myResID, myEntryID, myHeight, myWidth, myPegSides, myOffset, myOptions);
  1319.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1320.             break;
  1321.         }
  1322.         
  1323.         case kShowNodePicture: {         // overlay a picture (in the front buffer) in a particular node
  1324.             UInt32        myHeight;
  1325.             UInt32        myWidth;
  1326.             UInt32        myPegSides;
  1327.             UInt32        myOffset;
  1328.  
  1329.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %ld %ld %ld", &myResID, &myEntryID, &myNodeID, &myHeight, &myWidth, &myPegSides, &myOffset, &myOptions);
  1330.             sprintf(myCmdLine, "ShowPicture %ld %ld %ld %ld %ld %ld %ld", myResID, myEntryID, myHeight, myWidth, myPegSides, myOffset, myOptions);
  1331.             VRScript_EnlistNodeEntryCommand(theWindowObject, myNodeID, kVRDoIt_Forever, 0, myCmdLine);
  1332.             break;
  1333.         }
  1334.         
  1335.          case kAtTime: {                     // execute a command at a specific time
  1336.             UInt32        myTicks;
  1337.             UInt32        myMode;
  1338.             UInt32        myRepeat;
  1339.             UInt32        myPeriod;
  1340.             
  1341.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %ld %ld %ld %s", &myTicks, &myMode, &myNodeID, &myRepeat, &myPeriod, &myMaxTimes, &myOptions, myCmdLine);
  1342.             VRScript_UnpackString(myCmdLine);
  1343.             VRScript_EnlistTimedCommand(theWindowObject, myTicks, myMode, myNodeID, myRepeat, myPeriod, myMaxTimes, myOptions, myCmdLine);
  1344.             break;
  1345.         }
  1346.         
  1347.          case kAtAppLaunch:                 // execute a command when the application is launched
  1348.             sscanf(theCommandLine, "%*s %ld %s", &myOptions, myCmdLine);
  1349.             VRScript_UnpackString(myCmdLine);
  1350.             VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine);
  1351.             break;
  1352.         
  1353.          case kAtAppQuit:                 // execute a command when the application is quit
  1354.             sscanf(theCommandLine, "%*s %ld %s", &myOptions, myCmdLine);
  1355.             VRScript_UnpackString(myCmdLine);
  1356.             VRScript_EnlistQuitCommand(theWindowObject, myOptions, myCmdLine);
  1357.             break;
  1358.         
  1359.          case kAtMouseOverHSID:             // execute a command when the mouse is over a hot spot, targeted by ID
  1360.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %s", &myNodeID, &myHotSpotID, &myMaxTimes, &myOptions, myCmdLine);
  1361.             VRScript_UnpackString(myCmdLine);
  1362.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, myHotSpotID, (OSType)0, myMaxTimes, myOptions, myCmdLine);
  1363.             break;
  1364.         
  1365.          case kAtMouseOverHSType: {         // execute a command when the mouse is over a hot spot, targeted by type
  1366.             OSType        myType;
  1367.             char        myHotSpotType[kMaxOSTypeLength];
  1368.                     
  1369.             sscanf(theCommandLine, "%*s %ld %s %ld %ld %s", &myNodeID, &myHotSpotType, &myMaxTimes, &myOptions, myCmdLine);
  1370.             myType = VRScript_StringToOSType(myHotSpotType);
  1371.             
  1372.             VRScript_UnpackString(myCmdLine);
  1373.             VRScript_EnlistMouseOverHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, myMaxTimes, myOptions, myCmdLine);
  1374.             break;
  1375.         }
  1376.         
  1377.          case kAtClickHSID:                 // execute a command when the mouse is clicked on a hot spot, targeted by ID
  1378.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %s", &myNodeID, &myHotSpotID, &myMaxTimes, &myOptions, myCmdLine);
  1379.             VRScript_UnpackString(myCmdLine);
  1380.             VRScript_EnlistClickHSCommand(theWindowObject, myNodeID, myHotSpotID, (OSType)0, myMaxTimes, myOptions, myCmdLine);
  1381.             break;
  1382.         
  1383.          case kAtClickHSType: {             // execute a command when the mouse is clicked on a hot spot, targeted by type
  1384.             OSType        myType;
  1385.             char        myHotSpotType[kMaxOSTypeLength];
  1386.                     
  1387.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %s", &myNodeID, &myHotSpotType, &myMaxTimes, &myOptions, myCmdLine);
  1388.             myType = VRScript_StringToOSType(myHotSpotType);
  1389.  
  1390.             VRScript_UnpackString(myCmdLine);
  1391.             VRScript_EnlistClickHSCommand(theWindowObject, myNodeID, (UInt32)0, myType, myMaxTimes, myOptions, myCmdLine);
  1392.             break;
  1393.         }
  1394.         
  1395.          case kAtClickCustomButton:        // execute a command when the mouse is clicked on the custom button in the controller bar
  1396.             sscanf(theCommandLine, "%*s %ld %ld %ld %s", &myNodeID, &myMaxTimes, &myOptions, myCmdLine);
  1397.             VRScript_UnpackString(myCmdLine);
  1398.             VRScript_EnlistClickCustomButtonCommand(theWindowObject, myNodeID, myMaxTimes, myOptions, myCmdLine);
  1399.             break;
  1400.         
  1401.          case kAtClickSprite:            // execute a command when the mouse is clicked on a sprite            
  1402.             sscanf(theCommandLine, "%*s %ld %ld %ld %s", &myNodeID, &myMaxTimes, &myOptions, myCmdLine);
  1403.             VRScript_UnpackString(myCmdLine);
  1404.             VRScript_EnlistClickSpriteCommand(theWindowObject, myNodeID, myMaxTimes, myOptions, myCmdLine);
  1405.             break;
  1406.         
  1407.          case kAtNodeEntry:                 // execute a command when the specified node is entered
  1408.             sscanf(theCommandLine, "%*s %ld %ld %ld %s", &myNodeID, &myMaxTimes, &myOptions, myCmdLine);
  1409.             VRScript_UnpackString(myCmdLine);
  1410.             VRScript_EnlistNodeEntryCommand(theWindowObject, myNodeID, myMaxTimes, myOptions, myCmdLine);
  1411.             break;
  1412.         
  1413.          case kAtNodeExit: {                 // execute a command when the specified node is exited
  1414.             UInt32        myFromNodeID;
  1415.             UInt32        myToNodeID;
  1416.             
  1417.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld %s", &myFromNodeID, &myToNodeID, &myMaxTimes, &myOptions, myCmdLine);
  1418.             VRScript_UnpackString(myCmdLine);
  1419.             VRScript_EnlistNodeExitCommand(theWindowObject, myFromNodeID, myToNodeID, myMaxTimes, myOptions, myCmdLine);
  1420.             break;
  1421.         }
  1422.         
  1423.          case kAtPanAngle:                 // execute a command at the specified pan angle
  1424.             sscanf(theCommandLine, "%*s %ld %f %f %ld %ld %s", &myNodeID, &myMinAngle, &myMaxAngle, &myMaxTimes, &myOptions, myCmdLine);
  1425.             VRScript_EnlistAngleCommand(theWindowObject, kVREntry_PanAngleCmd, myNodeID, myMinAngle, myMaxAngle, myMaxTimes, myOptions, myCmdLine);
  1426.             break;
  1427.         
  1428.          case kAtTiltAngle:                 // execute a command at the specified tilt angle
  1429.             sscanf(theCommandLine, "%*s %ld %f %f %ld %ld %s", &myNodeID, &myMinAngle, &myMaxAngle, &myMaxTimes, &myOptions, myCmdLine);
  1430.             VRScript_EnlistAngleCommand(theWindowObject, kVREntry_TiltAngleCmd, myNodeID, myMinAngle, myMaxAngle, myMaxTimes, myOptions, myCmdLine);
  1431.             break;
  1432.         
  1433.          case kAtZoomAngle:                 // execute a command at the specified zoom angle
  1434.             sscanf(theCommandLine, "%*s %ld %f %f %ld %ld %s", &myNodeID, &myMinAngle, &myMaxAngle, &myMaxTimes, &myOptions, myCmdLine);
  1435.             VRScript_EnlistAngleCommand(theWindowObject, kVREntry_FOVAngleCmd, myNodeID, myMinAngle, myMaxAngle, myMaxTimes, myOptions, myCmdLine);
  1436.             break;
  1437.         
  1438.          case kDoBoth: {                     // execute both of the specified commands
  1439.             char        myCmdLine1[kMaxCmdLineLength];
  1440.             char        myCmdLine2[kMaxCmdLineLength];
  1441.  
  1442.             sscanf(theCommandLine, "%*s %ld %s %s", &myOptions, myCmdLine1, myCmdLine2);
  1443.             VRScript_UnpackString(myCmdLine1);
  1444.             VRScript_UnpackString(myCmdLine2);
  1445.             VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine1);
  1446.             VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine2);
  1447.             break;
  1448.         }
  1449.         
  1450.          case kDoNothing:                 // don't do anything; this can be useful to trigger some side effects of an "At" command
  1451.             break;
  1452.         
  1453.          case kPlayMovie: {                 // play a QuickTime movie
  1454.              float        myScale;
  1455.              float        myWidth;
  1456.              UInt32        myKeyRed;
  1457.              UInt32        myKeyGreen;
  1458.              UInt32        myKeyBlue;
  1459.             UInt32        myUseBuffer;
  1460.             UInt32        myUseCenter;
  1461.             UInt32        myUseKey;
  1462.             UInt32        myUseHide;
  1463.             UInt32        myUseDir;
  1464.             UInt32        myRotate;
  1465.             UInt32        myMode;
  1466.              float        myVolAngle;
  1467.             
  1468.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %ld %ld %ld %ld %ld %ld %ld %ld %ld %f %ld %ld %s", 
  1469.                     &myEntryID,
  1470.                     &myPanAngle,
  1471.                     &myTiltAngle,
  1472.                     &myScale, 
  1473.                     &myWidth, 
  1474.                     &myKeyRed, 
  1475.                     &myKeyGreen, 
  1476.                     &myKeyBlue, 
  1477.                     &myUseBuffer,
  1478.                     &myUseCenter,
  1479.                     &myUseKey,
  1480.                     &myUseHide,
  1481.                     &myUseDir,
  1482.                     &myRotate,
  1483.                     &myVolAngle,
  1484.                     &myMode,
  1485.                     &myOptions,
  1486.                     myPathName);
  1487.                 
  1488.             myPanAngle = QTVRUtils_DegreesToRadians(myPanAngle);
  1489.             myTiltAngle = QTVRUtils_DegreesToRadians(myTiltAngle);
  1490.             myVolAngle = QTVRUtils_DegreesToRadians(myVolAngle);
  1491.             myWidth = QTVRUtils_DegreesToRadians(myWidth);
  1492.  
  1493.             if (theWindowObject == NULL)
  1494.                 break;
  1495.  
  1496.             myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  1497.  
  1498.             VRScript_UnpackString(myPathName);
  1499.             VRMoov_PlayMovie(theWindowObject,
  1500.                     myNodeID,
  1501.                     myEntryID,
  1502.                     myPanAngle,
  1503.                     myTiltAngle,
  1504.                     myScale, 
  1505.                     myWidth, 
  1506.                     myKeyRed, 
  1507.                     myKeyGreen, 
  1508.                     myKeyBlue, 
  1509.                     (Boolean)myUseBuffer,
  1510.                     (Boolean)myUseCenter,
  1511.                     (Boolean)myUseKey,
  1512.                     (Boolean)myUseHide,
  1513.                     (Boolean)myUseDir,
  1514.                     (Boolean)myRotate,
  1515.                     myVolAngle,
  1516.                     myMode,
  1517.                     myOptions,
  1518.                     myPathName);
  1519.             break;
  1520.         }
  1521.         
  1522.          case kPlayTransMovie:             // play a QuickTime movie as a transition between two nodes
  1523.             sscanf(theCommandLine, "%*s %ld %s", &myOptions, myPathName);
  1524.             VRMoov_PlayTransitionMovie(theWindowObject, myOptions, myPathName);
  1525.             break;
  1526.         
  1527.          case kPlayTransEffect: {         // play a QuickTime video effect as a transition between two nodes
  1528.             char        myEffectType[kMaxOSTypeLength];
  1529.             UInt32        myFromNodeID;
  1530.             UInt32        myToNodeID;
  1531.             long        myEffectNum;
  1532.             OSType        myType;
  1533.             
  1534.             sscanf(theCommandLine, "%*s %ld %ld %ld %s %ld %ld", &myFromNodeID, &myToNodeID, &myMaxTimes, myEffectType, &myEffectNum, &myOptions);
  1535.  
  1536.             // convert the string to an OSType
  1537.             myType = VRScript_StringToOSType(myEffectType);
  1538.  
  1539.             VRScript_EnlistTransitionEffect(theWindowObject, myFromNodeID, myToNodeID, myMaxTimes, myType, myEffectNum, myOptions);
  1540.             break;
  1541.         }
  1542.         
  1543.         case kMoveScreen: {                 // shift the movie screen center
  1544.             QTVRFloatPoint    myCenter;
  1545.             float            myHoriz;
  1546.             float            myVert;
  1547.  
  1548.             sscanf(theCommandLine, "%*s %f %f %ld", &myHoriz, &myVert, &myOptions);
  1549.             myHoriz = QTVRUtils_DegreesToRadians(myHoriz);
  1550.             myVert = QTVRUtils_DegreesToRadians(myVert);
  1551.             VRMoov_GetEmbeddedMovieCenter(theWindowObject, &myCenter);
  1552.             myCenter.x += myHoriz;
  1553.             myCenter.y += myVert;
  1554.             VRMoov_SetEmbeddedMovieCenter(theWindowObject, &myCenter);
  1555.             break;
  1556.         }
  1557.         
  1558.         case kBeep:                        // play the system beep
  1559.             DoBeep();
  1560.             break;
  1561.         
  1562.         case kProcessScript:            // open and process a script file (synchronously!)
  1563.             sscanf(theCommandLine, "%*s %ld %s", &myOptions, myPathName);
  1564.             VRScript_OpenScriptFile(theWindowObject, myPathName);
  1565.             break;
  1566.         
  1567. #if QD3D_AVAIL
  1568.         case kCreateBox: {                 // create a box
  1569.             float        myX, myY, myZ;
  1570.             float        myXSize, myYSize, myZSize;
  1571.  
  1572.             if (!gHasQuickDraw3D)
  1573.                 break;
  1574.                 
  1575.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myXSize, &myYSize, &myZSize, &myOptions);
  1576.             VR3DObjects_EnlistBox(theWindowObject, myEntryID, myX, myY, myZ, myXSize, myYSize, myZSize, myOptions);
  1577.             break;
  1578.         }
  1579.  
  1580.         case kCreateCone: {                 // create a cone
  1581.             float        myX, myY, myZ;
  1582.             float        myMajRad, myMinRad, myHeight;
  1583.  
  1584.             if (!gHasQuickDraw3D15)
  1585.                 break;
  1586.                 
  1587.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myMajRad, &myMinRad, &myHeight, &myOptions);
  1588.             VR3DObjects_EnlistCone(theWindowObject, myEntryID, myX, myY, myZ, myMajRad, myMinRad, myHeight, myOptions);
  1589.             break;
  1590.         }
  1591.  
  1592.         case kCreateCylinder: {             // create a cylinder
  1593.             float        myX, myY, myZ;
  1594.             float        myMajRad, myMinRad, myHeight;
  1595.  
  1596.             if (!gHasQuickDraw3D15)
  1597.                 break;
  1598.                 
  1599.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myMajRad, &myMinRad, &myHeight, &myOptions);
  1600.             VR3DObjects_EnlistCylinder(theWindowObject, myEntryID, myX, myY, myZ, myMajRad, myMinRad, myHeight, myOptions);
  1601.             break;
  1602.         }
  1603.  
  1604.         case kCreateEllipsoid: {         // create an ellipsoid
  1605.             float        myX, myY, myZ;
  1606.             float        myMajRad, myMinRad, myHeight;
  1607.  
  1608.             if (!gHasQuickDraw3D15)
  1609.                 break;
  1610.                 
  1611.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myMajRad, &myMinRad, &myHeight, &myOptions);
  1612.             VR3DObjects_EnlistEllipsoid(theWindowObject, myEntryID, myX, myY, myZ, myMajRad, myMinRad, myHeight, myOptions);
  1613.             break;
  1614.         }
  1615.  
  1616.         case kCreateTorus: {             // create a torus
  1617.             float        myX, myY, myZ;
  1618.             float        myMajRad, myMinRad, myHeight, myRatio;
  1619.  
  1620.             if (!gHasQuickDraw3D15)
  1621.                 break;
  1622.                 
  1623.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myMajRad, &myMinRad, &myHeight, &myRatio, &myOptions);
  1624.             VR3DObjects_EnlistTorus(theWindowObject, myEntryID, myX, myY, myZ, myMajRad, myMinRad, myHeight, myRatio, myOptions);
  1625.             break;
  1626.         }
  1627.  
  1628.         case kCreateRectangle: {         // create a rectangle
  1629.             float        myX, myY, myZ;
  1630.             float        myX1, myY1, myZ1, myX2, myY2, myZ2, myX3, myY3, myZ3, myX4, myY4, myZ4;
  1631.  
  1632.             if (!gHasQuickDraw3D15)
  1633.                 break;
  1634.                 
  1635.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myX1, &myY1, &myZ1, &myX2, &myY2, &myZ2, &myX3, &myY3, &myZ3, &myX4, &myY4, &myZ4, &myOptions);
  1636.             VR3DObjects_EnlistRectangle(theWindowObject, myEntryID, myX, myY, myZ, myX1, myY1, myZ1, myX2, myY2, myZ2, myX3, myY3, myZ3, myX4, myY4, myZ4, myOptions);
  1637.             break;
  1638.         }
  1639.  
  1640.         case kOpen3DMFFile: {             // load a 3D object contained in a 3DMF file
  1641.             float        myX, myY, myZ;
  1642.  
  1643.             if (!gHasQuickDraw3D)
  1644.                 break;
  1645.                 
  1646.             sscanf(theCommandLine, "%*s %ld %f %f %f %ld %s", &myEntryID, &myX, &myY, &myZ, &myOptions, myPathName);
  1647.             VR3DObjects_Enlist3DMFFile(theWindowObject, myEntryID, myX, myY, myZ, myOptions, myPathName);
  1648.             break;
  1649.         }
  1650.  
  1651.         case kSet3DObjLocation: {        // set the location of a 3D object
  1652.             float        myX, myY, myZ;
  1653.  
  1654.             if (theWindowObject == NULL)
  1655.                 break;
  1656.                 
  1657.             sscanf(theCommandLine, "%*s %ld %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myOptions);
  1658.             VR3DObjects_SetLocation(theWindowObject, myEntryID, myX, myY, myZ, myOptions);
  1659.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1660.             break;
  1661.         }
  1662.         
  1663.         case kSet3DObjColor: {            // set the color of a 3D object
  1664.             float        myRed, myGreen, myBlue;
  1665.  
  1666.             if (theWindowObject == NULL)
  1667.                 break;
  1668.                 
  1669.             sscanf(theCommandLine, "%*s %ld %f %f %f %ld", &myEntryID, &myRed, &myGreen, &myBlue, &myOptions);
  1670.             VR3DObjects_SetColor(theWindowObject, myEntryID, myRed, myGreen, myBlue, myOptions);
  1671.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1672.             break;
  1673.         }
  1674.         
  1675.         case kSet3DObjTransp: {            // set the transparency level of a 3D object
  1676.             float        myRed, myGreen, myBlue;
  1677.  
  1678.             if (theWindowObject == NULL)
  1679.                 break;
  1680.                 
  1681.             sscanf(theCommandLine, "%*s %ld %f %f %f %ld", &myEntryID, &myRed, &myGreen, &myBlue, &myOptions);
  1682.             VR3DObjects_SetTransparency(theWindowObject, myEntryID, myRed, myGreen, myBlue, myOptions);
  1683.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1684.             break;
  1685.         }
  1686.         
  1687.         case kSet3DObjInterp:            // set the interpolation style of a 3D object
  1688.             if (theWindowObject == NULL)
  1689.                 break;
  1690.                 
  1691.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myUInt32, &myOptions);
  1692.             VR3DObjects_SetInterpolation(theWindowObject, myEntryID, myUInt32, myOptions);
  1693.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1694.             break;
  1695.         
  1696.         case kSet3DObjBackface:            // set the backfacing style of a 3D object
  1697.             if (theWindowObject == NULL)
  1698.                 break;
  1699.                 
  1700.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myUInt32, &myOptions);
  1701.             VR3DObjects_SetBackfacing(theWindowObject, myEntryID, myUInt32, myOptions);
  1702.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1703.             break;
  1704.         
  1705.         case kSet3DObjFill:                // set the fill style of a 3D object
  1706.             if (theWindowObject == NULL)
  1707.                 break;
  1708.  
  1709.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myUInt32, &myOptions);
  1710.             VR3DObjects_SetFill(theWindowObject, myEntryID, myUInt32, myOptions);
  1711.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1712.             break;
  1713.         
  1714.         case kSet3DObjRotation: {        // set the rotation factors of a 3D object
  1715.             float        myX, myY, myZ;
  1716.  
  1717.             if (theWindowObject == NULL)
  1718.                 break;
  1719.                 
  1720.             sscanf(theCommandLine, "%*s %ld %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myOptions);
  1721.             myX = QTVRUtils_DegreesToRadians(myX);
  1722.             myY = QTVRUtils_DegreesToRadians(myY);
  1723.             myZ = QTVRUtils_DegreesToRadians(myZ);
  1724.             VR3DObjects_SetRotation(theWindowObject, myEntryID, myX, myY, myZ, myOptions);
  1725.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1726.             break;
  1727.         }
  1728.         
  1729.         case kSet3DObjRotState:            // set the rotation state of a 3D object
  1730.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myUInt32, &myOptions);
  1731.             VR3DObjects_SetRotationState(theWindowObject, myEntryID, myUInt32, myOptions);
  1732.             break;
  1733.         
  1734.         case kSet3DObjVisState:            // set the visibility state of a 3D object
  1735.             if (theWindowObject == NULL)
  1736.                 break;
  1737.                 
  1738.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myUInt32, &myOptions);
  1739.             VR3DObjects_SetVisibleState(theWindowObject, myEntryID, myUInt32, myOptions);
  1740.             QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  1741.             break;
  1742.         
  1743.         case kSet3DObjTexture:            // set the texture of a 3D object
  1744.             sscanf(theCommandLine, "%*s %ld %ld %ld %s", &myEntryID, &myUInt32, &myOptions, myPathName);
  1745.             VR3DObjects_SetTexture(theWindowObject, myEntryID, (Boolean)myUInt32, myOptions, myPathName);
  1746.             break;
  1747.         
  1748.         case kDestroy3DObject: {        // destroy a 3D object; note that the options are not yet defined
  1749.             VRScriptGenericPtr     myPointer;
  1750.  
  1751.             sscanf(theCommandLine, "%*s %ld %ld", &myEntryID, &myOptions);
  1752.             myPointer = VRScript_GetObjectByEntryID(theWindowObject, kVREntry_QD3DObject, myEntryID);
  1753.             if (myPointer != NULL)
  1754.                 VRScript_DelistEntry(theWindowObject, myPointer);
  1755.             break;
  1756.         }
  1757. #endif // QD3D_AVAIL
  1758.         
  1759.         case kSet3DSndLocation: {        // set the location of a localized sound
  1760.             float        myX, myY, myZ;
  1761.  
  1762.             sscanf(theCommandLine, "%*s %ld %f %f %f %ld", &myEntryID, &myX, &myY, &myZ, &myOptions);
  1763.             VRSound_SetLocation(theWindowObject, myEntryID, myX, myY, myZ, myOptions);
  1764.             VRSound_Update3DSoundEnv(theWindowObject);
  1765.             break;
  1766.         }
  1767.  
  1768.         case kSetVariable: {            // set the value of a variable; variables are used only in If commands
  1769.             char                    myVarName[kMaxVarNameLength];
  1770.             SInt32                    myVarValue;
  1771.             VRScriptVariablePtr        myPointer;
  1772.             
  1773.             sscanf(theCommandLine, "%*s %s %ld %ld", myVarName, &myVarValue, &myOptions);
  1774.             myPointer = VRScript_GetVariableEntry(theWindowObject, myVarName);
  1775.             
  1776.             if (myPointer == NULL) {
  1777.                 VRScript_EnlistVariable(theWindowObject, myVarName, myVarValue);
  1778.             } else {
  1779.                 if (myOptions == kVRValue_Absolute)
  1780.                     myPointer->fValue = myVarValue;
  1781.                 if (myOptions == kVRValue_Relative)
  1782.                     myPointer->fValue += myVarValue;
  1783.             }
  1784.             
  1785.             break;
  1786.         }
  1787.  
  1788.         case kIf: {                        // evaluate the expression "var op value"; execute a command if true
  1789.             char                    myVarName[kMaxVarNameLength];
  1790.             char                    myOperation[kMaxVarOpLength];
  1791.             SInt32                    myVarValue;
  1792.             VRScriptVariablePtr        myPointer;
  1793.             
  1794.             sscanf(theCommandLine, "%*s %s %s %ld %ld %s", myVarName, myOperation, &myVarValue, &myOptions, myCmdLine);
  1795.             myPointer = VRScript_GetVariableEntry(theWindowObject, myVarName);
  1796.             
  1797.             if (myPointer != NULL) {
  1798.                 Boolean                myRunCommand = false;
  1799.  
  1800.                 // find the appropriate operation and test for its satisfaction
  1801.                 if ((strcmp(myOperation, "=") == 0) || (strcmp(myOperation, "==") == 0))
  1802.                     myRunCommand = (myPointer->fValue == myVarValue);
  1803.                 else if (strcmp(myOperation, "!=") == 0)
  1804.                     myRunCommand = (myPointer->fValue != myVarValue);
  1805.                 else if (strcmp(myOperation, "<") == 0)
  1806.                     myRunCommand = (myPointer->fValue < myVarValue);
  1807.                 else if (strcmp(myOperation, "<=") == 0)
  1808.                     myRunCommand = (myPointer->fValue <= myVarValue);
  1809.                 else if (strcmp(myOperation, ">") == 0)
  1810.                     myRunCommand = (myPointer->fValue > myVarValue);
  1811.                 else if (strcmp(myOperation, ">=") == 0)
  1812.                     myRunCommand = (myPointer->fValue >= myVarValue);        
  1813.                     
  1814.                 if (myRunCommand) {
  1815.                     VRScript_UnpackString(myCmdLine);
  1816.                     VRScript_ProcessScriptCommandLine(theWindowObject, myCmdLine);
  1817.                 }
  1818.             }
  1819.             
  1820.             break;
  1821.         }
  1822.  
  1823.         case kSetSpriteVisState:        // set the visibility of a sprite on or off
  1824.             if (theWindowObject == NULL)
  1825.                 break;
  1826.                 
  1827.             sscanf(theCommandLine, "%*s %ld %ld %ld", &mySpriteID, &myUInt32, &myOptions);
  1828.             VRSprites_SetVisibleState(theWindowObject, (QTAtomID)mySpriteID, myUInt32, myOptions);
  1829.             break;
  1830.  
  1831.         case kSetSpriteLayer:            // set the layer of a sprite
  1832.             if (theWindowObject == NULL)
  1833.                 break;
  1834.                 
  1835.             sscanf(theCommandLine, "%*s %ld %ld %ld", &mySpriteID, &myUInt32, &myOptions);
  1836.             VRSprites_SetLayer(theWindowObject, (QTAtomID)mySpriteID, myUInt32, myOptions);
  1837.             break;
  1838.  
  1839.         case kSetSpriteGraphicsMode:    // set the graphics mode of a sprite
  1840.             if (theWindowObject == NULL)
  1841.                 break;
  1842.                 
  1843.             sscanf(theCommandLine, "%*s %ld %ld %ld", &mySpriteID, &myUInt32, &myOptions);
  1844.             VRSprites_SetGraphicsMode(theWindowObject, (QTAtomID)mySpriteID, myUInt32, myOptions);
  1845.             break;
  1846.  
  1847.         case kSetSpriteImageIndex:        // set the image index of a sprite
  1848.             if (theWindowObject == NULL)
  1849.                 break;
  1850.                 
  1851.             sscanf(theCommandLine, "%*s %ld %ld %ld", &mySpriteID, &myUInt32, &myOptions);
  1852.             VRSprites_SetImageIndex(theWindowObject, (QTAtomID)mySpriteID, (short)myUInt32, myOptions);
  1853.             break;
  1854.  
  1855.         case kSetSpriteMatrix: {        // set the matrix of a sprite
  1856.             float            myR0C0, myR0C1, myR0C2, myR1C0, myR1C1, myR1C2, myR2C0, myR2C1, myR2C2;
  1857.             MatrixRecord    myMatrix;
  1858.  
  1859.             if (theWindowObject == NULL)
  1860.                 break;
  1861.                 
  1862.             sscanf(theCommandLine, "%*s %ld %f %f %f %f %f %f %f %f %f %ld", &mySpriteID, &myR0C0, &myR0C1, &myR0C2, &myR1C0, &myR1C1, &myR1C2, &myR2C0, &myR2C1, &myR2C2, &myOptions);
  1863.             myMatrix.matrix[0][0] = FloatToFixed(myR0C0);
  1864.             myMatrix.matrix[0][1] = FloatToFixed(myR0C1);
  1865.             myMatrix.matrix[0][2] = FloatToFract(myR0C2);
  1866.             myMatrix.matrix[1][0] = FloatToFixed(myR1C0);
  1867.             myMatrix.matrix[1][1] = FloatToFixed(myR1C1);
  1868.             myMatrix.matrix[1][2] = FloatToFract(myR1C2);
  1869.             myMatrix.matrix[2][0] = FloatToFixed(myR2C0);
  1870.             myMatrix.matrix[2][1] = FloatToFixed(myR2C1);
  1871.             myMatrix.matrix[2][2] = FloatToFract(myR2C2);
  1872.             VRSprites_SetMatrix(theWindowObject, (QTAtomID)mySpriteID, &myMatrix, myOptions);
  1873.             break;
  1874.         }
  1875.         
  1876.         case kSetSpriteLocation: {        // set the location of a sprite;
  1877.                                         // the h and v values are pixels relative to the sprite track's origin
  1878.             UInt32            myH, myV;
  1879.             Point            myPoint;
  1880.  
  1881.             if (theWindowObject == NULL)
  1882.                 break;
  1883.                 
  1884.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld", &mySpriteID, &myH, &myV, &myOptions);
  1885.             myPoint.h = (short)myH;
  1886.             myPoint.v = (short)myV;
  1887.             VRSprites_SetLocation(theWindowObject, (QTAtomID)mySpriteID, &myPoint, myOptions);
  1888.             break;
  1889.         }
  1890.  
  1891.         case kSetTrackVolume:             // set the volume of a sound track in an enlisted QuickTime movie
  1892.         case kSetTrackState:             // enable or disable a track in an enlisted QuickTime movie
  1893.         case kSetTrackLayer: {             // set the layer of a track in an enlisted QuickTime movie
  1894.             UInt32                myValue;
  1895.             UInt32                myIndex;
  1896.             VRScriptMoviePtr    myMoviePtr = NULL;
  1897.             Track                myTrack = NULL;
  1898.  
  1899.             if (theWindowObject == NULL)
  1900.                 break;
  1901.             
  1902.             sscanf(theCommandLine, "%*s %ld %ld %ld %ld", &myEntryID, &myValue, &myIndex, &myOptions);
  1903.  
  1904.             myMoviePtr = (VRScriptMoviePtr)VRScript_GetObjectByEntryID(theWindowObject, kVREntry_QTMovie, myEntryID);
  1905.             if (myMoviePtr != NULL) {
  1906.                 if (myMoviePtr->fMovie != NULL)
  1907.                     myTrack = GetMovieIndTrack(myMoviePtr->fMovie, myIndex);
  1908.                     
  1909.                 if (myTrack == NULL)
  1910.                      break;
  1911.                 
  1912.                 switch (myCode) {
  1913.                     case kSetTrackVolume:
  1914.                         if (myOptions == kVRValue_Absolute)
  1915.                             SetTrackVolume(myTrack, (short)myValue);
  1916.                         else
  1917.                             SetTrackVolume(myTrack, (short)myValue + GetTrackVolume(myTrack));
  1918.                         break;
  1919.                     
  1920.                     case kSetTrackState:
  1921.                         if (myValue == kVRState_Toggle)
  1922.                             myValue = (UInt32)!GetTrackEnabled(myTrack);
  1923.             
  1924.                         SetTrackEnabled(myTrack, (Boolean)myValue);
  1925.                         break;
  1926.                     
  1927.                     case kSetTrackLayer:
  1928.                         SetTrackLayer(myTrack, (short)myValue);
  1929.                         break;
  1930.                 }     
  1931.             }
  1932.             
  1933.             break;
  1934.         }
  1935.                 
  1936.         case kSetMovieTime:              // set the current time of the specified movie
  1937.         case kSetMovieRate:              // set the rate of the specified movie
  1938.         case kSetMovieTimeScale: {         // set the time scale of the specified movie
  1939.             VRScriptMoviePtr    myMoviePtr = NULL;
  1940.  
  1941.             if (theWindowObject == NULL)
  1942.                 break;
  1943.             
  1944.             sscanf(theCommandLine, "%*s %ld %ld %ld", &myEntryID, &myUInt32, &myOptions);
  1945.  
  1946.             myMoviePtr = (VRScriptMoviePtr)VRScript_GetObjectByEntryID(theWindowObject, kVREntry_QTMovie, myEntryID);
  1947.             if (myMoviePtr != NULL)
  1948.                 if (myMoviePtr->fMovie != NULL)
  1949.                     switch (myCode) {
  1950.                         case kSetMovieTime:
  1951.                             SetMovieTimeValue(myMoviePtr->fMovie, (TimeValue)myUInt32);
  1952.                             break;
  1953.                         case kSetMovieRate:
  1954.                             SetMovieRate(myMoviePtr->fMovie, (Fixed)myUInt32);
  1955.                             break;
  1956.                         case kSetMovieTimeScale:
  1957.                             SetMovieTimeScale(myMoviePtr->fMovie, (TimeScale)myUInt32);
  1958.                             break;
  1959.                     }
  1960.             
  1961.             break;
  1962.         }
  1963.     
  1964.         default:
  1965.             // if we got here, we encountered an unrecognized command;
  1966.             // just silently ignore it
  1967.             break;
  1968.             
  1969.     } // switch (myCode)
  1970.     
  1971. }
  1972.  
  1973.  
  1974. //////////
  1975. //
  1976. // VRScript_SetCurrentDirectory
  1977. // Set the current or default directory. All filenames specified in the script file are taken as relative
  1978. // to this directory.
  1979. //
  1980. // A bit of terminology: on MacOS, the directory that is searched when only a filename is given is called
  1981. // the "default directory"; on Windows, this is called the "current directory".
  1982. //
  1983. // NOTE: The theFSSpecPtr parameter must specify *a file* in the directory to be made current. That file
  1984. // does not need to exist, however.
  1985. //
  1986. //////////
  1987.  
  1988. void VRScript_SetCurrentDirectory (FSSpecPtr theFSSpecPtr)
  1989. {
  1990. #if TARGET_OS_MAC
  1991.     HSetVol(NULL, theFSSpecPtr->vRefNum, theFSSpecPtr->parID);
  1992. #elif TARGET_OS_WIN32
  1993.     char         myFilePath[MAX_PATH];
  1994.  
  1995.     FSSpecToNativePathName(theFSSpecPtr, myFilePath, MAX_PATH, kDirectoryPathOnly);
  1996.     SetCurrentDirectory(myFilePath);
  1997. #endif
  1998. }
  1999.  
  2000.  
  2001. //////////
  2002. //
  2003. // VRScript_SetCurrentMovie
  2004. // Set the QuickTime movie currently displayed in the window attached to theWindowObject.
  2005. //
  2006. //////////
  2007.  
  2008. void VRScript_SetCurrentMovie (WindowObject theWindowObject, UInt32 theOverlayType, UInt32 theNameType, UInt32 theOptions, char *thePathName)
  2009. {
  2010. #pragma unused(theOverlayType, theOptions)
  2011.     FSSpec                myFSSpec;
  2012.     Movie                myMovie = NULL;
  2013.     MovieController        myMC = NULL;
  2014.     short                myRefNum = 0;
  2015.     Movie                myPrevMovie = NULL;
  2016.     MovieController        myPrevMC = NULL;
  2017.     short                myPrevRefNum = 0;
  2018.     short                myResID = 0;
  2019.     WindowReference        myWindow = NULL;
  2020.     QTVRInstance        myInstance = NULL;
  2021. #if TARGET_OS_WIN32
  2022.     char                 myFileName[MAX_PATH];
  2023. #endif
  2024.     OSErr                myErr = noErr;
  2025.  
  2026.     // make sure we have a valid window object and movie window
  2027.     if (theWindowObject == NULL)
  2028.         return;
  2029.  
  2030.     myWindow = (**theWindowObject).fWindow;
  2031.     if (myWindow == NULL)
  2032.         return;
  2033.     
  2034.     // get the previous movie and controller
  2035.     myPrevMovie = (**theWindowObject).fMovie;
  2036.     myPrevMC = (**theWindowObject).fController;
  2037.     myPrevRefNum = (**theWindowObject).fFileRefNum;
  2038.     
  2039.     // find the target QuickTime movie file
  2040.     switch (theNameType) {
  2041.         case kVRRelativePath:
  2042.         case kVRAbsolutePath:
  2043.             myErr = FSMakeFSSpec(0, 0, c2pstr(thePathName), &myFSSpec);
  2044.             if (myErr != noErr)
  2045.                 goto bail;
  2046.                 
  2047.             // open the specified movie file;
  2048.             // ideally, we'd like read and write permission, but we'll settle for read-only permission
  2049.             myErr = OpenMovieFile(&myFSSpec, &myRefNum, fsRdWrPerm);
  2050.             if (myErr != noErr)
  2051.                 myErr = OpenMovieFile(&myFSSpec, &myRefNum, fsRdPerm);
  2052.  
  2053.             // if we couldn't open the file with even just read-only permission, bail....
  2054.             if (myErr != noErr)
  2055.                 goto bail;
  2056.  
  2057.             // now fetch the first movie from the file
  2058.             myResID = 0;
  2059.             myErr = NewMovieFromFile(&myMovie, myRefNum, &myResID, NULL, newMovieActive, NULL);
  2060.             if (myErr != noErr)
  2061.                 goto bail;
  2062.             
  2063.             CloseMovieFile(myRefNum);
  2064.             break;
  2065.             
  2066.         case kVRAbsoluteURL: {
  2067.             char     *myString;
  2068.             
  2069.             myResID = 0;
  2070.             myMovie = URLUtils_NewMovieFromURL(thePathName, newMovieActive, &myResID);
  2071.             
  2072.             myString = URLUtils_GetURLBasename(thePathName);
  2073.             FSMakeFSSpec(0, 0, c2pstr(myString), &myFSSpec);
  2074.             free(myString);
  2075.             
  2076.             break;
  2077.         }
  2078.             
  2079.         case kVRRelativeURL:
  2080.             // to be supplied
  2081.             break;
  2082.             
  2083.         default:
  2084.             goto bail;    // unknown pathname type
  2085.     }
  2086.     
  2087.     // make sure the movie uses the window GWorld in all situations
  2088.     SetMovieGWorld(myMovie, (CGrafPtr)GetPortFromWindowReference(myWindow), GetGWorldDevice((CGrafPtr)GetPortFromWindowReference(myWindow)));
  2089.  
  2090.     // create and configure the movie controller
  2091.     myMC = SetupMovieWindowWithController(myMovie, myWindow, false);
  2092.     if (myMC == NULL)
  2093.         goto bail;
  2094.         
  2095.     //////////
  2096.     //
  2097.     // in with the new....
  2098.     //
  2099.     //////////
  2100.     
  2101.     // set the window title
  2102. #if TARGET_OS_MAC
  2103.     SetWTitle(myWindow, myFSSpec.name);
  2104. #elif TARGET_OS_WIN32
  2105.     FSSpecToNativePathName(&myFSSpec, myFileName, MAX_PATH, kFileNameOnly);
  2106.     SetWindowText(myWindow, myFileName);
  2107. #endif
  2108.  
  2109.     // get the QTVR instance
  2110.     QTVRGetQTVRInstance(&myInstance, QTVRGetQTVRTrack(myMovie, 1), myMC);
  2111.     
  2112.     // store movie info in the window record
  2113.     (**theWindowObject).fMovie = myMovie;
  2114.     (**theWindowObject).fController = myMC;
  2115.     (**theWindowObject).fFileResID = myResID;
  2116.     (**theWindowObject).fFileRefNum = myRefNum;
  2117.     (**theWindowObject).fCanResizeWindow = true;
  2118.     (**theWindowObject).fDirty = false;
  2119.     (**theWindowObject).fInstance = myInstance;
  2120.     (**theWindowObject).fFileFSSpec = myFSSpec;
  2121.  
  2122.     // redraw the window
  2123.     MCInvalidate(myMC, (GrafPtr)GetPortFromWindowReference(myWindow), MCGetWindowRgn(myMC, (GrafPtr)GetPortFromWindowReference(myWindow)));
  2124.  
  2125.     // reset the cursor
  2126.     InitCursor();
  2127.     
  2128.     //////////
  2129.     //
  2130.     // out with the old....
  2131.     //
  2132.     //////////
  2133.     
  2134.     // we'd like to be able to just call DisposeMovieController and DisposeMovie on the
  2135.     // previous controller and movie, but we can't; the reason is that this function might
  2136.     // have been called in response to a user event (such as a click on a hot spot) that
  2137.     // was passed to MCIsPlayerEvent in our main event loop. Experience tells me that it's
  2138.     // not good to dispose of the movie controller inside code called by MCIsPlayerEvent.
  2139.     // Our solution is to defer disposal until a safe time.
  2140.     
  2141.     gPreviousMC = myPrevMC;
  2142.     gPreviousMovie = myPrevMovie;
  2143.         
  2144.     if (myPrevRefNum != 0)
  2145.         CloseMovieFile(myPrevRefNum);
  2146.  
  2147.     VRMoov_StartMovie(myMovie);
  2148.         
  2149.     return;
  2150.     
  2151. bail:
  2152.     // if we arrived here, an error occurred and we could not load the new movie;
  2153.     // undo any work we did to install the new movie
  2154.     if (myMC != NULL)
  2155.         DisposeMovieController(myMC);
  2156.         
  2157.     if (myMovie != NULL)
  2158.         DisposeMovie(myMovie);
  2159.         
  2160.     if (myRefNum != 0)
  2161.         CloseMovieFile(myRefNum);
  2162. }
  2163.  
  2164.  
  2165. //////////
  2166. //
  2167. // VRScript_SetControllerBarState
  2168. // Set the state of the controller bar.
  2169. //
  2170. //////////
  2171.  
  2172. void VRScript_SetControllerBarState (WindowObject theWindowObject, Boolean theState, UInt32 theOptions)
  2173. {
  2174. #pragma unused(theOptions)
  2175.  
  2176.     if (theWindowObject == NULL)
  2177.         return;
  2178.  
  2179.     if (theState == kVRState_Toggle)
  2180.         theState = !MCGetVisible((**theWindowObject).fController);
  2181.     
  2182.     MCSetVisible((**theWindowObject).fController, theState);
  2183. }
  2184.  
  2185.  
  2186. //////////
  2187. //
  2188. // VRScript_SetControllerButtonState
  2189. // Set the state of the specified button (or text display) in the controller bar.
  2190. //
  2191. //////////
  2192.  
  2193. void VRScript_SetControllerButtonState (WindowObject theWindowObject, UInt32 theButton, Boolean theState, UInt32 theOptions)
  2194. {
  2195. #pragma unused(theOptions)
  2196.     
  2197.     long    myButton;
  2198.     
  2199.     if (theWindowObject == NULL)
  2200.         return;
  2201.         
  2202.     if ((**theWindowObject).fController == NULL)
  2203.         return;
  2204.  
  2205.     // convert VRScript's enum into the actual value expected by the movie controller
  2206.     switch (theButton) {
  2207.         case kVRButton_Step:            myButton = mcFlagSuppressStepButtons;            break;
  2208.         case kVRButton_Speaker:            myButton = mcFlagSuppressSpeakerButton;            break;
  2209.         case kVRButton_GoBack:            myButton = mcFlagQTVRSuppressBackBtn;            break;
  2210.         case kVRButton_ZoomInOut:        myButton = mcFlagQTVRSuppressZoomBtns;            break;
  2211.         case kVRButton_ShowHotSpots:    myButton = mcFlagQTVRSuppressHotSpotBtn;        break;
  2212.         case kVRButton_Translate:        myButton = mcFlagQTVRSuppressTranslateBtn;        break;
  2213.         case kVRButton_HelpText:        myButton = mcFlagQTVRSuppressHelpText;            break;
  2214.         case kVRButton_HotSpotNames:    myButton = mcFlagQTVRSuppressHotSpotNames;        break;
  2215.         case kVRButton_Custom:            myButton = mcFlagsUseCustomButton;                break;
  2216.         default:
  2217.             break;
  2218.     }
  2219.  
  2220.     // set the correct state of the button        
  2221.     switch (theState) {
  2222.         case kVRState_Hide:
  2223.             QTUtils_HideControllerButton((**theWindowObject).fController, myButton);
  2224.             break;
  2225.         case kVRState_Show:
  2226.             QTUtils_ShowControllerButton((**theWindowObject).fController, myButton);
  2227.             break;
  2228.         case kVRState_Toggle:
  2229.             QTUtils_ToggleControllerButton((**theWindowObject).fController, myButton);
  2230.             break;
  2231.         default:
  2232.             break;
  2233.     }
  2234. }
  2235.  
  2236.  
  2237. //////////
  2238. //
  2239. // VRScript_SetResizeState
  2240. // Set the state of window resizing.
  2241. //
  2242. //////////
  2243.  
  2244. void VRScript_SetResizeState (WindowObject theWindowObject, Boolean theState, UInt32 theOptions)
  2245. {
  2246. #pragma unused(theOptions)
  2247.  
  2248.     Rect            myRect;
  2249.  
  2250.     if (theWindowObject == NULL)
  2251.         return;
  2252.  
  2253.     if (theState == kVRState_Toggle)
  2254.         theState = !(**theWindowObject).fCanResizeWindow;
  2255.  
  2256.     (**theWindowObject).fCanResizeWindow = theState;
  2257.     
  2258.     // set size of growable window
  2259.     if ((**theWindowObject).fCanResizeWindow)
  2260.         MacSetRect(&myRect, gLimitRect.left, gLimitRect.top, gLimitRect.right, gLimitRect.bottom);
  2261.     else
  2262.         MacSetRect(&myRect, 0, 0, 0, 0);
  2263.     
  2264.     MCDoAction((**theWindowObject).fController, mcActionSetGrowBoxBounds, &myRect);
  2265.     QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  2266. }
  2267.  
  2268.  
  2269. //////////
  2270. //
  2271. // VRScript_SetAngleConstraints
  2272. // Set the pan, tilt, or zoom constraints.
  2273. // Note: this function expects theMinAngle and theMaxAngle to be in *degrees*.
  2274. //
  2275. //////////
  2276.  
  2277. void VRScript_SetAngleConstraints (WindowObject theWindowObject, UInt16 theKind, float theMinAngle, float theMaxAngle, UInt32 theOptions)
  2278. {
  2279.     float    myMinAngle;
  2280.     float    myMaxAngle;
  2281.  
  2282.     if (theWindowObject == NULL)
  2283.         return;
  2284.     
  2285.     myMinAngle = QTVRUtils_DegreesToRadians(theMinAngle);
  2286.     myMaxAngle = QTVRUtils_DegreesToRadians(theMaxAngle);
  2287.     
  2288.     if (theOptions == kVRValue_Relative) {
  2289.         float    myCurrMin;
  2290.         float    myCurrMax;
  2291.         OSErr    myErr;
  2292.  
  2293.         myErr = QTVRGetConstraints((**theWindowObject).fInstance, theKind, &myCurrMin, &myCurrMax);
  2294.         if (myErr == noErr) {
  2295.             myMinAngle += myCurrMin;
  2296.             myMaxAngle += myCurrMax;
  2297.         }
  2298.     }
  2299.                 
  2300.     QTVRSetConstraints((**theWindowObject).fInstance, theKind, myMinAngle, myMaxAngle);
  2301.     QTVRUpdate((**theWindowObject).fInstance, kQTVRCurrentMode);
  2302. }
  2303.  
  2304.  
  2305. //////////
  2306. //
  2307. // VRScript_OpenResourceFile
  2308. // Open the specified resource file and add it to the application's resource chain.
  2309. // Returns the file reference number, if successful, or -1 otherwise.
  2310. //
  2311. //////////
  2312.  
  2313. short VRScript_OpenResourceFile (WindowObject theWindowObject, UInt32 theOptions, char *thePathName)
  2314. {
  2315. #pragma unused(theWindowObject, theOptions)
  2316.  
  2317.     FSSpec        myFSSpec;
  2318.     short        myRefNum = -1;
  2319.  
  2320.     // we accept either full pathnames or partial pathnames specified relative to the default directory
  2321.     // on the default volume
  2322.     FSMakeFSSpec(0, 0L, c2pstr(thePathName), &myFSSpec);
  2323.         
  2324.     myRefNum = FSpOpenResFile(&myFSSpec, fsRdPerm);
  2325.     if (myRefNum == -1)
  2326.         ;                    // no error handling yet....
  2327.         
  2328.     return(myRefNum);
  2329. }
  2330.  
  2331.  
  2332. //////////
  2333. //
  2334. // VRScript_EnlistSound
  2335. // Install an ambient sound.
  2336. //
  2337. //////////
  2338.  
  2339. VRScriptSoundPtr VRScript_EnlistSound (WindowObject theWindowObject, UInt32 theNodeID, UInt32 theResID, UInt32 theEntryID, UInt32 theMode, UInt32 theFade, UInt32 theOptions, SndChannelPtr theChannel, SndListHandle theResource)
  2340. {
  2341.     VRScriptSoundPtr        myPointer;
  2342.     ApplicationDataHdl        myAppData;
  2343.     
  2344.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2345.     if (myAppData == NULL)
  2346.         return(NULL);
  2347.     
  2348.     myPointer = (VRScriptSoundPtr)NewPtrClear(sizeof(VRScriptSound));
  2349.     if (myPointer != NULL) {
  2350.         myPointer->fEntryType = kVREntry_Sound;
  2351.         myPointer->fEntryID = theEntryID;
  2352.         myPointer->fNodeID = theNodeID;
  2353.         myPointer->fOptions = theOptions;
  2354.         myPointer->fMode = theMode;
  2355.         myPointer->fSoundContainer = kVRSound_SoundResource;
  2356.         myPointer->fResID = theResID;
  2357.         myPointer->fResourceData = theResource;
  2358.         myPointer->fChannel = theChannel;
  2359.         myPointer->fFadeWhenStopping = (Boolean)theFade;
  2360.         myPointer->fSoundIsLocalized = false;
  2361.         myPointer->fSource = 0;
  2362.         myPointer->fLocation.x = 0.0;
  2363.         myPointer->fLocation.y = 0.0;
  2364.         myPointer->fLocation.z = 0.0;
  2365.         myPointer->fProjAngle = 0.0;
  2366.         myPointer->fNextEntry = (VRScriptSoundPtr)(**myAppData).fListArray[kVREntry_Sound];
  2367.         (**myAppData).fListArray[kVREntry_Sound] = (VRScriptGenericPtr)myPointer;
  2368.     }
  2369.     
  2370.     return(myPointer);
  2371. }
  2372.  
  2373.  
  2374. //////////
  2375. //
  2376. // VRScript_EnlistLocalizedSound
  2377. // Install a localized sound.
  2378. //
  2379. //////////
  2380.  
  2381. VRScriptSoundPtr VRScript_EnlistLocalizedSound (WindowObject theWindowObject, UInt32 theNodeID, UInt32 theResID, UInt32 theEntryID, float theX, float theY, float theZ, float theProjAngle, UInt32 theMode, UInt32 theFade, UInt32 theOptions, SndChannelPtr theChannel, SndListHandle theResource, SSpSourceReference theSource)
  2382. {
  2383.     VRScriptSoundPtr        myPointer;
  2384.     ApplicationDataHdl        myAppData;
  2385.     
  2386.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2387.     if (myAppData == NULL)
  2388.         return(NULL);
  2389.  
  2390.     myPointer = (VRScriptSoundPtr)NewPtrClear(sizeof(VRScriptSound));
  2391.     if (myPointer != NULL) {
  2392.         myPointer->fEntryType = kVREntry_Sound;
  2393.         myPointer->fEntryID = theEntryID;
  2394.         myPointer->fNodeID = theNodeID;
  2395.         myPointer->fOptions = theOptions;
  2396.         myPointer->fMode = theMode;
  2397.         myPointer->fSoundContainer = kVRSound_SoundResource;
  2398.         myPointer->fResID = theResID;
  2399.         myPointer->fResourceData = theResource;
  2400.         myPointer->fChannel = theChannel;
  2401.         myPointer->fSource = theSource;
  2402.         myPointer->fLocation.x = theX;
  2403.         myPointer->fLocation.y = theY;
  2404.         myPointer->fLocation.z = theZ;
  2405.         myPointer->fProjAngle = theProjAngle;
  2406.         myPointer->fFadeWhenStopping = (Boolean)theFade;
  2407.         myPointer->fSoundIsLocalized = true;
  2408.         myPointer->fNextEntry = (VRScriptSoundPtr)(**myAppData).fListArray[kVREntry_Sound];
  2409.         (**myAppData).fListArray[kVREntry_Sound] = (VRScriptGenericPtr)myPointer;
  2410.     }
  2411.     
  2412.     return(myPointer);
  2413. }
  2414.  
  2415.  
  2416. //////////
  2417. //
  2418. // VRScript_EnlistMovie
  2419. // Install a QuickTime movie by adding the given information to our linked list.
  2420. //
  2421. //////////
  2422.  
  2423. VRScriptMoviePtr VRScript_EnlistMovie (
  2424.                 WindowObject theWindowObject,
  2425.                 UInt32 theNodeID,
  2426.                 UInt32 theEntryID,
  2427.                 float thePanAngle,
  2428.                 float theTiltAngle,
  2429.                 float theScale, 
  2430.                 float theWidth, 
  2431.                 UInt32 theKeyRed, 
  2432.                 UInt32 theKeyGreen, 
  2433.                 UInt32 theKeyBlue, 
  2434.                 Boolean theUseBuffer,
  2435.                 Boolean theUseCenter,
  2436.                 Boolean theUseKey,
  2437.                 Boolean theUseHide,
  2438.                 Boolean theUseDir,
  2439.                 Boolean theRotate,
  2440.                 float theVolAngle,
  2441.                 UInt32 theMode,
  2442.                 UInt32 theOptions,
  2443.                 char *thePathName)
  2444. {
  2445.     VRScriptMoviePtr        myPointer;
  2446.     ApplicationDataHdl        myAppData;
  2447.  
  2448.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2449.     if (myAppData == NULL)
  2450.         return(NULL);
  2451.  
  2452.     myPointer = (VRScriptMoviePtr)NewPtrClear(sizeof(VRScriptMovie));
  2453.     if (myPointer != NULL) {
  2454.         myPointer->fEntryType = kVREntry_QTMovie;
  2455.         myPointer->fEntryID = theEntryID;
  2456.         myPointer->fNodeID = theNodeID;
  2457.         myPointer->fOptions = theOptions;
  2458.         myPointer->fMode = theMode;
  2459.         myPointer->fMovie = NULL;
  2460.         myPointer->fMovieGWorld = NULL;
  2461.         myPointer->fMoviePixMap = NULL;
  2462.         myPointer->fMovieCenter.x = thePanAngle;
  2463.         myPointer->fMovieCenter.y = theTiltAngle;
  2464.         myPointer->fMovieScale = theScale;
  2465.         myPointer->fMovieWidth = theWidth;
  2466.         myPointer->fUseMovieGWorld = theUseBuffer;
  2467.         myPointer->fUseMovieCenter = theUseCenter;
  2468.         myPointer->fQTMovieHasSound = false;        // we don't really know until we open the file....
  2469.         myPointer->fQTMovieHasVideo = false;        // we don't really know until we open the file....
  2470.         myPointer->fCompositeMovie = theUseKey;
  2471.         myPointer->fUseHideRegion = theUseHide;
  2472.         myPointer->fChromaColor.red = (unsigned short)theKeyRed;
  2473.         myPointer->fChromaColor.green = (unsigned short)theKeyGreen;
  2474.         myPointer->fChromaColor.blue = (unsigned short)theKeyBlue;
  2475.         myPointer->fHideRegion = NULL;
  2476.         myPointer->fSoundIsLocalized = theUseDir;
  2477.         myPointer->fDoRotateMovie = theRotate;
  2478.         myPointer->fVolAngle = theVolAngle;
  2479.         myPointer->fPathname = malloc(strlen(thePathName) + 1);
  2480.         strncpy(myPointer->fPathname, thePathName, strlen(thePathName) + 1);
  2481.         myPointer->fNextEntry = (VRScriptMoviePtr)(**myAppData).fListArray[kVREntry_QTMovie];
  2482.         (**myAppData).fListArray[kVREntry_QTMovie] = (VRScriptGenericPtr)myPointer;
  2483.     }
  2484.     
  2485.     return(myPointer);
  2486. }
  2487.  
  2488.  
  2489. //////////
  2490. //
  2491. // VRScript_Enlist3DObject
  2492. // Install a 3D object.
  2493. //
  2494. //////////
  2495.  
  2496. #if QD3D_AVAIL
  2497. void VRScript_Enlist3DObject (WindowObject theWindowObject, TQ3GroupObject theGroup, UInt32 theEntryID, float theX, float theY, float theZ, UInt32 theOptions)
  2498. {
  2499.     VRScript3DObjPtr        myPointer;
  2500.     ApplicationDataHdl        myAppData;
  2501.     TQ3Point3D                myPoint;
  2502.     
  2503.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2504.     if (myAppData == NULL)
  2505.         return;
  2506.     
  2507.     myPointer = (VRScript3DObjPtr)NewPtrClear(sizeof(VRScript3DObj));
  2508.     if (myPointer != NULL) {
  2509.         myPointer->fEntryType = kVREntry_QD3DObject;
  2510.         myPointer->fEntryID = theEntryID;
  2511.         myPointer->fOptions = theOptions;
  2512.         myPointer->fModel = theGroup;
  2513.  
  2514.         myPointer->fInterpolation = Q3InterpolationStyle_New((TQ3InterpolationStyle)kDefaultInterpolation);
  2515.         myPointer->fBackFacing = Q3BackfacingStyle_New((TQ3BackfacingStyle)kDefaultBackfacing);
  2516.         myPointer->fFillStyle = Q3FillStyle_New((TQ3FillStyle)kDefaultFill);
  2517.         
  2518.         Q3Matrix4x4_SetIdentity(&(myPointer->fRotation));    
  2519.         myPointer->fRotateFactors.x = kDefaultRotateRadians;        // default rotation factors
  2520.         myPointer->fRotateFactors.y = kDefaultRotateRadians;
  2521.         myPointer->fRotateFactors.y = kDefaultRotateRadians;
  2522.             
  2523.         Q3Point3D_Set(&myPoint, -1.0 * theX, theY, -1.0 * theZ);
  2524.         myPointer->fGroupCenter = myPoint;
  2525.         myPointer->fGroupScale = kDefaultScale;
  2526.         myPointer->fTexture = NULL;
  2527.         myPointer->fTextureIsMovie = false;
  2528.         myPointer->fModelIsVisible = true;
  2529.         myPointer->fModelIsAnimated = false;
  2530.         myPointer->fNextEntry = (VRScript3DObjPtr)(**myAppData).fListArray[kVREntry_QD3DObject];
  2531.         (**myAppData).fListArray[kVREntry_QD3DObject] = (VRScriptGenericPtr)myPointer;
  2532.     }
  2533. }
  2534. #endif
  2535.  
  2536.  
  2537. //////////
  2538. //
  2539. // VRScript_EnlistOverlayPicture
  2540. // Install an overlay picture by adding the given information to our linked list.
  2541. //
  2542. //////////
  2543.  
  2544. VRScriptPicturePtr VRScript_EnlistOverlayPicture (WindowObject theWindowObject, UInt32 theResID, UInt32 theEntryID, UInt32 theHeight, UInt32 theWidth, UInt32 thePegSides, UInt32 theOffset, PicHandle theResource, UInt32 theOptions)
  2545. {
  2546.     VRScriptPicturePtr        myPointer;
  2547.     ApplicationDataHdl        myAppData;
  2548.  
  2549.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2550.     if (myAppData == NULL)
  2551.         return(NULL);
  2552.  
  2553.     myPointer = (VRScriptPicturePtr)NewPtrClear(sizeof(VRScriptPicture));
  2554.     if (myPointer != NULL) {
  2555.         myPointer->fEntryType = kVREntry_OverlayPicture;
  2556.         myPointer->fEntryID = theEntryID;
  2557.         myPointer->fNodeID = 0;
  2558.         myPointer->fOptions = theOptions;
  2559.         myPointer->fResID = theResID;
  2560.         myPointer->fBoxHeight = theHeight;
  2561.         myPointer->fBoxWidth = theWidth;
  2562.         myPointer->fPegSides = thePegSides;
  2563.         myPointer->fOffset = theOffset;
  2564.         myPointer->fResourceData = theResource;
  2565.         myPointer->fNextEntry = (VRScriptPicturePtr)(**myAppData).fListArray[kVREntry_OverlayPicture];
  2566.         (**myAppData).fListArray[kVREntry_OverlayPicture] = (VRScriptGenericPtr)myPointer;
  2567.     }
  2568.     
  2569.     return(myPointer);
  2570. }
  2571.  
  2572.  
  2573. //////////
  2574. //
  2575. // VRScript_EnlistTimedCommand
  2576. // Install a timed-activated command by adding the given information to our linked list.
  2577. //
  2578. //////////
  2579.  
  2580. void VRScript_EnlistTimedCommand (WindowObject theWindowObject, UInt32 theTicks, UInt32 theMode, UInt32 theNodeID, UInt32 theRepeat, UInt32 thePeriod, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2581. {
  2582.     VRScriptAtTimePtr        myPointer;
  2583.     ApplicationDataHdl        myAppData;
  2584.  
  2585.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2586.     if (myAppData == NULL)
  2587.         return;
  2588.  
  2589.     myPointer = (VRScriptAtTimePtr)NewPtrClear(sizeof(VRScriptAtTime));
  2590.     if (myPointer != NULL) {
  2591.         myPointer->fEntryType = kVREntry_TimedCommand;
  2592.         myPointer->fNodeID = theNodeID;
  2593.         myPointer->fOptions = theOptions;
  2594.         myPointer->fTime = theTicks;
  2595.         myPointer->fMode = theMode;
  2596.         myPointer->fTimeInstalled = gAbsoluteElapsedTime;
  2597.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2598.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2599.         myPointer->fRepeat = (Boolean)theRepeat;
  2600.         myPointer->fPeriod = thePeriod;
  2601.         myPointer->fMaxExecutions = theMaxTimes;
  2602.         myPointer->fNextEntry = (VRScriptAtTimePtr)(**myAppData).fListArray[kVREntry_TimedCommand];
  2603.         (**myAppData).fListArray[kVREntry_TimedCommand] = (VRScriptGenericPtr)myPointer;
  2604.     }
  2605. }
  2606.  
  2607.  
  2608. //////////
  2609. //
  2610. // VRScript_EnlistQuitCommand
  2611. // Install an application-quit command by adding the given information to our linked list.
  2612. //
  2613. //////////
  2614.  
  2615. void VRScript_EnlistQuitCommand (WindowObject theWindowObject, UInt32 theOptions, char *theCmdLine)
  2616. {
  2617.     VRScriptAtQuitPtr        myPointer;
  2618.     ApplicationDataHdl        myAppData;
  2619.  
  2620.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2621.     if (myAppData == NULL)
  2622.         return;
  2623.  
  2624.     myPointer = (VRScriptAtQuitPtr)NewPtrClear(sizeof(VRScriptAtQuit));
  2625.     if (myPointer != NULL) {
  2626.         myPointer->fEntryType = kVREntry_QuitCommand;
  2627.         myPointer->fOptions = theOptions;
  2628.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2629.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2630.         myPointer->fNextEntry = (VRScriptAtQuitPtr)(**myAppData).fListArray[kVREntry_QuitCommand];
  2631.         (**myAppData).fListArray[kVREntry_QuitCommand] = (VRScriptGenericPtr)myPointer;
  2632.     }
  2633. }
  2634.  
  2635.  
  2636. //////////
  2637. //
  2638. // VRScript_EnlistMouseOverHSCommand
  2639. // Install a mouse-over hot spot command by adding the given information to our linked list.
  2640. //
  2641. //////////
  2642.  
  2643. void VRScript_EnlistMouseOverHSCommand (WindowObject theWindowObject, UInt32 theNodeID, UInt32 theHotSpotID, OSType theHotSpotType, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2644. {
  2645.     VRScriptAtMOHSPtr        myPointer;
  2646.     ApplicationDataHdl        myAppData;
  2647.  
  2648.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2649.     if (myAppData == NULL)
  2650.         return;
  2651.  
  2652.     myPointer = (VRScriptAtMOHSPtr)NewPtrClear(sizeof(VRScriptAtMOHS));
  2653.     if (myPointer != NULL) {
  2654.         myPointer->fEntryType = kVREntry_MouseOverHS;
  2655.         myPointer->fNodeID = theNodeID;
  2656.         myPointer->fOptions = theOptions;                            // the hot spot action selector
  2657.         myPointer->fSelectByID = theHotSpotID > 0 ? true : false;
  2658.         myPointer->fHotSpotID = theHotSpotID;
  2659.         myPointer->fHotSpotType = theHotSpotType;
  2660.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2661.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2662.         myPointer->fMaxExecutions = theMaxTimes;
  2663.         myPointer->fNextEntry = (VRScriptAtMOHSPtr)(**myAppData).fListArray[kVREntry_MouseOverHS];
  2664.         (**myAppData).fListArray[kVREntry_MouseOverHS] = (VRScriptGenericPtr)myPointer;
  2665.     }
  2666. }
  2667.  
  2668.  
  2669. //////////
  2670. //
  2671. // VRScript_EnlistClickHSCommand
  2672. // Install a hot spot click command by adding the given information to our linked list.
  2673. //
  2674. //////////
  2675.  
  2676. void VRScript_EnlistClickHSCommand (WindowObject theWindowObject, UInt32 theNodeID, UInt32 theHotSpotID, OSType theHotSpotType, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2677. {
  2678.     VRScriptClickHSPtr        myPointer;
  2679.     ApplicationDataHdl        myAppData;
  2680.  
  2681.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2682.     if (myAppData == NULL)
  2683.         return;
  2684.  
  2685.     myPointer = (VRScriptClickHSPtr)NewPtrClear(sizeof(VRScriptClickHS));
  2686.     if (myPointer != NULL) {
  2687.         myPointer->fEntryType = kVREntry_ClickHS;
  2688.         myPointer->fNodeID = theNodeID;
  2689.         myPointer->fOptions = theOptions;
  2690.         myPointer->fSelectByID = theHotSpotID > 0 ? true : false;
  2691.         myPointer->fHotSpotID = theHotSpotID;
  2692.         myPointer->fHotSpotType = theHotSpotType;
  2693.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2694.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2695.         myPointer->fMaxExecutions = theMaxTimes;
  2696.         myPointer->fNextEntry = (VRScriptClickHSPtr)(**myAppData).fListArray[kVREntry_ClickHS];
  2697.         (**myAppData).fListArray[kVREntry_ClickHS] = (VRScriptGenericPtr)myPointer;
  2698.     }
  2699. }
  2700.  
  2701.  
  2702. //////////
  2703. //
  2704. // VRScript_EnlistClickCustomButtonCommand
  2705. // Install a custom button click command by adding the given information to our linked list.
  2706. //
  2707. //////////
  2708.  
  2709. void VRScript_EnlistClickCustomButtonCommand (WindowObject theWindowObject, UInt32 theNodeID, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2710. {
  2711.     VRScriptClickCustomPtr    myPointer;
  2712.     ApplicationDataHdl        myAppData;
  2713.  
  2714.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2715.     if (myAppData == NULL)
  2716.         return;
  2717.  
  2718.     myPointer = (VRScriptClickCustomPtr)NewPtrClear(sizeof(VRScriptClickCustom));
  2719.     if (myPointer != NULL) {
  2720.         myPointer->fEntryType = kVREntry_ClickCustom;
  2721.         myPointer->fNodeID = theNodeID;
  2722.         myPointer->fOptions = theOptions;
  2723.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2724.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2725.         myPointer->fMaxExecutions = theMaxTimes;
  2726.         myPointer->fNextEntry = (VRScriptClickCustomPtr)(**myAppData).fListArray[kVREntry_ClickCustom];
  2727.         (**myAppData).fListArray[kVREntry_ClickCustom] = (VRScriptGenericPtr)myPointer;
  2728.     }
  2729. }
  2730.  
  2731.  
  2732. //////////
  2733. //
  2734. // VRScript_EnlistClickSpriteCommand
  2735. // Install a sprite click command by adding the given information to our linked list.
  2736. //
  2737. //////////
  2738.  
  2739. void VRScript_EnlistClickSpriteCommand (WindowObject theWindowObject, UInt32 theNodeID, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2740. {
  2741.     VRScriptClickSpritePtr    myPointer;
  2742.     ApplicationDataHdl        myAppData;
  2743.  
  2744.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2745.     if (myAppData == NULL)
  2746.         return;
  2747.  
  2748.     myPointer = (VRScriptClickSpritePtr)NewPtrClear(sizeof(VRScriptClickSprite));
  2749.     if (myPointer != NULL) {
  2750.         myPointer->fEntryType = kVREntry_ClickSprite;
  2751.         myPointer->fNodeID = theNodeID;
  2752.         myPointer->fOptions = theOptions;
  2753.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2754.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2755.         myPointer->fMaxExecutions = theMaxTimes;
  2756.         myPointer->fNextEntry = (VRScriptClickSpritePtr)(**myAppData).fListArray[kVREntry_ClickSprite];
  2757.         (**myAppData).fListArray[kVREntry_ClickSprite] = (VRScriptGenericPtr)myPointer;
  2758.     }
  2759. }
  2760.  
  2761.  
  2762. //////////
  2763. //
  2764. // VRScript_EnlistNodeEntryCommand
  2765. // Install a node-entry command by adding the given information to our linked list.
  2766. //
  2767. //////////
  2768.  
  2769. void VRScript_EnlistNodeEntryCommand (WindowObject theWindowObject, UInt32 theNodeID, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2770. {
  2771.     VRScriptNodeInPtr        myPointer;
  2772.     ApplicationDataHdl        myAppData;
  2773.  
  2774.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2775.     if (myAppData == NULL)
  2776.         return;
  2777.  
  2778.     myPointer = (VRScriptNodeInPtr)NewPtrClear(sizeof(VRScriptNodeIn));
  2779.     if (myPointer != NULL) {
  2780.         myPointer->fEntryType = kVREntry_NodeEntry;
  2781.         myPointer->fNodeID = theNodeID;
  2782.         myPointer->fOptions = theOptions;
  2783.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2784.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2785.         myPointer->fMaxExecutions = theMaxTimes;
  2786.         myPointer->fNextEntry = (VRScriptNodeInPtr)(**myAppData).fListArray[kVREntry_NodeEntry];
  2787.         (**myAppData).fListArray[kVREntry_NodeEntry] = (VRScriptGenericPtr)myPointer;
  2788.     }
  2789. }
  2790.  
  2791.  
  2792. //////////
  2793. //
  2794. // VRScript_EnlistNodeExitCommand
  2795. // Install a node-exit command by adding the given information to our linked list.
  2796. //
  2797. //////////
  2798.  
  2799. void VRScript_EnlistNodeExitCommand (WindowObject theWindowObject, UInt32 theFromNodeID, UInt32 theToNodeID, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2800. {
  2801.     VRScriptNodeOutPtr        myPointer;
  2802.     ApplicationDataHdl        myAppData;
  2803.  
  2804.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2805.     if (myAppData == NULL)
  2806.         return;
  2807.  
  2808.     myPointer = (VRScriptNodeOutPtr)NewPtrClear(sizeof(VRScriptNodeOut));
  2809.     if (myPointer != NULL) {
  2810.         myPointer->fEntryType = kVREntry_NodeExit;
  2811.         myPointer->fOptions = theOptions;
  2812.         myPointer->fFromNodeID = theFromNodeID;
  2813.         myPointer->fToNodeID = theToNodeID;
  2814.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2815.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2816.         myPointer->fMaxExecutions = theMaxTimes;
  2817.         myPointer->fNextEntry = (VRScriptNodeOutPtr)(**myAppData).fListArray[kVREntry_NodeExit];
  2818.         (**myAppData).fListArray[kVREntry_NodeExit] = (VRScriptGenericPtr)myPointer;
  2819.     }
  2820. }
  2821.  
  2822.  
  2823. //////////
  2824. //
  2825. // VRScript_EnlistAngleCommand
  2826. // Install an angle-triggered command by adding the given information to our linked list.
  2827. // Note: this function expects theMinAngle and theMaxAngle to be in *degrees*.
  2828. //
  2829. //////////
  2830.  
  2831. void VRScript_EnlistAngleCommand (WindowObject theWindowObject, UInt32 theKind, UInt32 theNodeID, float theMinAngle, float theMaxAngle, SInt32 theMaxTimes, UInt32 theOptions, char *theCmdLine)
  2832. {
  2833.     VRScriptAtAnglePtr        myPointer;
  2834.     ApplicationDataHdl        myAppData;
  2835.  
  2836.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2837.     if (myAppData == NULL)
  2838.         return;
  2839.  
  2840.     theMinAngle = QTVRUtils_DegreesToRadians(theMinAngle);
  2841.     theMaxAngle = QTVRUtils_DegreesToRadians(theMaxAngle);
  2842.     VRScript_UnpackString(theCmdLine);
  2843.  
  2844.     myPointer = (VRScriptAtAnglePtr)NewPtrClear(sizeof(VRScriptAtAngle));
  2845.     if (myPointer != NULL) {
  2846.         myPointer->fEntryType = theKind;
  2847.         myPointer->fNodeID = theNodeID;
  2848.         myPointer->fOptions = theOptions;
  2849.         myPointer->fMinAngle = theMinAngle;
  2850.         myPointer->fMaxAngle = theMaxAngle;
  2851.         myPointer->fMaxExecutions = theMaxTimes;
  2852.         myPointer->fCommandLine = malloc(strlen(theCmdLine) + 1);
  2853.         strncpy(myPointer->fCommandLine, theCmdLine, strlen(theCmdLine) + 1);
  2854.         myPointer->fNextEntry = (VRScriptAtAnglePtr)(**myAppData).fListArray[theKind];
  2855.         (**myAppData).fListArray[theKind] = (VRScriptGenericPtr)myPointer;
  2856.     }
  2857. }
  2858.  
  2859.  
  2860. //////////
  2861. //
  2862. // VRScript_EnlistVariable
  2863. // Install a variable by adding the given information to our linked list.
  2864. //
  2865. //////////
  2866.  
  2867. void VRScript_EnlistVariable (WindowObject theWindowObject, char *theVarName, UInt32 theVarValue)
  2868. {
  2869.     VRScriptVariablePtr        myPointer;
  2870.     ApplicationDataHdl        myAppData;
  2871.  
  2872.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2873.     if (myAppData == NULL)
  2874.         return;
  2875.         
  2876.     myPointer = (VRScriptVariablePtr)NewPtrClear(sizeof(VRScriptVariable));
  2877.     if (myPointer != NULL) {
  2878.         myPointer->fEntryType = kVREntry_Variable;
  2879.         myPointer->fValue = theVarValue;
  2880.         myPointer->fVarName = malloc(strlen(theVarName) + 1);
  2881.         strncpy(myPointer->fVarName, theVarName, strlen(theVarName) + 1);
  2882.         myPointer->fNextEntry = (VRScriptVariablePtr)(**myAppData).fListArray[kVREntry_Variable];
  2883.         (**myAppData).fListArray[kVREntry_Variable] = (VRScriptGenericPtr)myPointer;
  2884.     }
  2885. }
  2886.  
  2887.  
  2888. //////////
  2889. //
  2890. // VRScript_EnlistTransition
  2891. // Install a transition effect by adding the given information to our linked list.
  2892. //
  2893. //////////
  2894.  
  2895. void VRScript_EnlistTransitionEffect (WindowObject theWindowObject, UInt32 theFromNodeID, UInt32 theToNodeID, SInt32 theMaxTimes, OSType theEffectType, long theEffectNum, UInt32 theOptions)
  2896. {
  2897.     VRScriptTransitionPtr    myPointer;
  2898.     ApplicationDataHdl        myAppData;
  2899.  
  2900.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2901.     if (myAppData == NULL)
  2902.         return;
  2903.         
  2904.     myPointer = (VRScriptTransitionPtr)NewPtrClear(sizeof(VRScriptTransition));
  2905.     if (myPointer != NULL) {
  2906.         myPointer->fEntryType = kVREntry_TransitionEffect;
  2907.         myPointer->fOptions = theOptions;
  2908.         myPointer->fFromNodeID = theFromNodeID;
  2909.         myPointer->fToNodeID = theToNodeID;
  2910.         myPointer->fMaxExecutions = theMaxTimes;
  2911.         myPointer->fEffectType = theEffectType;
  2912.         myPointer->fEffectNum = theEffectNum;
  2913.         myPointer->fNumberOfSteps = (long)kDefaultNumSteps;
  2914.         myPointer->fNextEntry = (VRScriptTransitionPtr)(**myAppData).fListArray[kVREntry_TransitionEffect];
  2915.         (**myAppData).fListArray[kVREntry_TransitionEffect] = (VRScriptGenericPtr)myPointer;
  2916.     }
  2917. }
  2918.  
  2919.  
  2920. //////////
  2921. //
  2922. // VRScript_DelistEntry
  2923. // Remove an entry from a linked list.
  2924. //
  2925. //////////
  2926.  
  2927. void VRScript_DelistEntry (WindowObject theWindowObject, VRScriptGenericPtr theEntryPtr)
  2928. {
  2929.     ApplicationDataHdl        myAppData;
  2930.     VRScriptGenericPtr        *myListHead;    // the *address* of the list head
  2931.     
  2932.     if (theEntryPtr == NULL)
  2933.         return;
  2934.     
  2935.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  2936.     if (myAppData != NULL) {
  2937.         
  2938.         // get the head of the specified list
  2939.         myListHead = &((**myAppData).fListArray[theEntryPtr->fEntryType]);
  2940.         
  2941.         // get rid of any memory associated with this entry
  2942.         switch (theEntryPtr->fEntryType) {
  2943.             case kVREntry_Sound:
  2944.                 VRSound_DumpEntryMem((VRScriptSoundPtr)theEntryPtr);            break;
  2945.             case kVREntry_QTMovie: 
  2946.                 VRMoov_DumpEntryMem((VRScriptMoviePtr)theEntryPtr);                break;
  2947.             case kVREntry_QD3DObject: 
  2948. #if QD3D_AVAIL
  2949.                 VR3DObjects_DumpEntryMem((VRScript3DObjPtr)theEntryPtr);
  2950. #endif
  2951.                 break;
  2952.             case kVREntry_OverlayPicture: 
  2953.                 VRPicture_DumpEntryMem((VRScriptPicturePtr)theEntryPtr);        break;
  2954.             case kVREntry_TimedCommand: 
  2955.                 free(((VRScriptAtTimePtr)theEntryPtr)->fCommandLine);            break;
  2956.             case kVREntry_QuitCommand: 
  2957.                 free(((VRScriptAtQuitPtr)theEntryPtr)->fCommandLine);            break;
  2958.             case kVREntry_MouseOverHS: 
  2959.                 free(((VRScriptAtMOHSPtr)theEntryPtr)->fCommandLine);            break;
  2960.             case kVREntry_ClickHS: 
  2961.                 free(((VRScriptClickHSPtr)theEntryPtr)->fCommandLine);            break;
  2962.             case kVREntry_ClickCustom: 
  2963.                 free(((VRScriptClickCustomPtr)theEntryPtr)->fCommandLine);        break;
  2964.             case kVREntry_ClickSprite: 
  2965.                 free(((VRScriptClickSpritePtr)theEntryPtr)->fCommandLine);        break;
  2966.             case kVREntry_NodeEntry: 
  2967.                 free(((VRScriptNodeInPtr)theEntryPtr)->fCommandLine);            break;
  2968.             case kVREntry_NodeExit: 
  2969.                 free(((VRScriptNodeOutPtr)theEntryPtr)->fCommandLine);            break;
  2970.             case kVREntry_PanAngleCmd: 
  2971.                 free(((VRScriptAtAnglePtr)theEntryPtr)->fCommandLine);            break;
  2972.             case kVREntry_TiltAngleCmd: 
  2973.                 free(((VRScriptAtAnglePtr)theEntryPtr)->fCommandLine);            break;
  2974.             case kVREntry_FOVAngleCmd: 
  2975.                 free(((VRScriptAtAnglePtr)theEntryPtr)->fCommandLine);            break;
  2976.             case kVREntry_Variable: 
  2977.                 free(((VRScriptVariablePtr)theEntryPtr)->fVarName);                break;
  2978.             case kVREntry_TransitionEffect: 
  2979.                 VREffects_DumpEntryMem((VRScriptTransitionPtr)theEntryPtr);        break;
  2980.             case kVREntry_Generic: 
  2981.             case kVREntry_Unknown: 
  2982.             default: 
  2983.                 return;
  2984.                 break;
  2985.         }
  2986.     
  2987.         // now drop the specified entry from the correct list
  2988.  
  2989.         if (*myListHead == theEntryPtr) {
  2990.             // the entry to remove is the head of the list; make the next entry the head    
  2991.             *myListHead = theEntryPtr->fNextEntry;
  2992.         } else {
  2993.             // the entry to remove is not the head of the list;
  2994.             // walk the list until we find the entry *before* the one to be removed
  2995.             VRScriptGenericPtr        myPointer;
  2996.  
  2997.             myPointer = *myListHead;
  2998.             while (myPointer != NULL) {
  2999.                 if (myPointer->fNextEntry == theEntryPtr) {
  3000.                     myPointer->fNextEntry = theEntryPtr->fNextEntry;
  3001.                     break;
  3002.                 }
  3003.                 myPointer = (VRScriptGenericPtr)(myPointer->fNextEntry);
  3004.             }
  3005.         }
  3006.     }
  3007.     
  3008.     DisposePtr((Ptr)theEntryPtr);
  3009. }
  3010.  
  3011.  
  3012. //////////
  3013. //
  3014. // VRScript_DeleteListOfType
  3015. // Delete the list containing entries of the specified type.
  3016. //
  3017. //////////
  3018.  
  3019. void VRScript_DeleteListOfType (WindowObject theWindowObject, UInt32 theEntryType)
  3020. {
  3021.     ApplicationDataHdl        myAppData;
  3022.     VRScriptGenericPtr        myPointer;
  3023.     
  3024.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3025.     if (myAppData == NULL)
  3026.         return;
  3027.         
  3028.     // get the head of specified list
  3029.     myPointer = (**myAppData).fListArray[theEntryType];
  3030.     while (myPointer != NULL) {
  3031.         VRScriptGenericPtr        myNext;
  3032.         
  3033.         myNext = myPointer->fNextEntry;
  3034.         
  3035.         // get rid of any memory associated with this entry
  3036.         switch (theEntryType) {
  3037.             case kVREntry_Sound: 
  3038.                 VRSound_DumpEntryMem((VRScriptSoundPtr)myPointer);                break;
  3039.             case kVREntry_QTMovie: 
  3040.                 VRMoov_DumpEntryMem((VRScriptMoviePtr)myPointer);                break;
  3041.             case kVREntry_QD3DObject: 
  3042. #if QD3D_AVAIL
  3043.                 VR3DObjects_DumpEntryMem((VRScript3DObjPtr)myPointer);
  3044. #endif
  3045.                                                                                 break;
  3046.             case kVREntry_OverlayPicture: 
  3047.                 VRPicture_DumpEntryMem((VRScriptPicturePtr)myPointer);            break;
  3048.             case kVREntry_TimedCommand: 
  3049.                 free(((VRScriptAtTimePtr)myPointer)->fCommandLine);                break;
  3050.             case kVREntry_QuitCommand: 
  3051.                 free(((VRScriptAtQuitPtr)myPointer)->fCommandLine);                break;
  3052.             case kVREntry_MouseOverHS: 
  3053.                 free(((VRScriptAtMOHSPtr)myPointer)->fCommandLine);                break;
  3054.             case kVREntry_ClickHS: 
  3055.                 free(((VRScriptClickHSPtr)myPointer)->fCommandLine);            break;
  3056.             case kVREntry_ClickCustom: 
  3057.                 free(((VRScriptClickCustomPtr)myPointer)->fCommandLine);        break;
  3058.             case kVREntry_ClickSprite: 
  3059.                 free(((VRScriptClickSpritePtr)myPointer)->fCommandLine);        break;
  3060.             case kVREntry_NodeEntry: 
  3061.                 free(((VRScriptNodeInPtr)myPointer)->fCommandLine);                break;
  3062.             case kVREntry_NodeExit: 
  3063.                 free(((VRScriptNodeOutPtr)myPointer)->fCommandLine);            break;
  3064.             case kVREntry_PanAngleCmd: 
  3065.                 free(((VRScriptAtAnglePtr)myPointer)->fCommandLine);            break;
  3066.             case kVREntry_TiltAngleCmd: 
  3067.                 free(((VRScriptAtAnglePtr)myPointer)->fCommandLine);            break;
  3068.             case kVREntry_FOVAngleCmd: 
  3069.                 free(((VRScriptAtAnglePtr)myPointer)->fCommandLine);            break;
  3070.             case kVREntry_Variable: 
  3071.                 free(((VRScriptVariablePtr)myPointer)->fVarName);                break;
  3072.             case kVREntry_TransitionEffect: 
  3073.                 VREffects_DumpEntryMem((VRScriptTransitionPtr)myPointer);        break;
  3074.             case kVREntry_Generic: 
  3075.             case kVREntry_Unknown: 
  3076.             default: 
  3077.                 return;
  3078.         }
  3079.         
  3080.         DisposePtr((Ptr)myPointer);
  3081.         myPointer = myNext;
  3082.     }
  3083.     
  3084.     (**myAppData).fListArray[theEntryType] = NULL;
  3085. }
  3086.  
  3087.  
  3088. //////////
  3089. //
  3090. // VRScript_DeleteAllLists
  3091. // Delete all lists used by this window.
  3092. //
  3093. //////////
  3094.  
  3095. void VRScript_DeleteAllLists (WindowObject theWindowObject)
  3096. {
  3097.     UInt32        myCount;
  3098.     
  3099.     for (myCount = kVRScript_FirstEntryType; myCount <= kVRScript_FinalEntryType; myCount++)
  3100.         VRScript_DeleteListOfType(theWindowObject, myCount);
  3101. }
  3102.  
  3103.  
  3104. //////////
  3105. //
  3106. // VRScript_GetObjectByEntryID
  3107. // Get the (first) list entry of the specified type having a specified entry ID.
  3108. //
  3109. //////////
  3110.  
  3111. VRScriptGenericPtr VRScript_GetObjectByEntryID (WindowObject theWindowObject, UInt32 theEntryType, UInt32 theEntryID)
  3112. {
  3113.     ApplicationDataHdl    myAppData;
  3114.     VRScriptGenericPtr    myPointer = NULL;
  3115.  
  3116.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);    
  3117.     if (myAppData == NULL)
  3118.         return(NULL);
  3119.     
  3120.     // walk our linked list to find the target object
  3121.     myPointer = (**myAppData).fListArray[theEntryType];
  3122.     while (myPointer != NULL) {
  3123.         if (myPointer->fEntryID == theEntryID)
  3124.             return(myPointer);
  3125.         myPointer = myPointer->fNextEntry;
  3126.     }
  3127.     
  3128.     return(NULL);
  3129. }
  3130.  
  3131.  
  3132. //////////
  3133. //
  3134. // VRScript_GetVariableEntry
  3135. // Get the (first) variable having the specified name.
  3136. //
  3137. //////////
  3138.  
  3139. VRScriptVariablePtr VRScript_GetVariableEntry (WindowObject theWindowObject, char *theVarName)
  3140. {
  3141.     ApplicationDataHdl    myAppData;
  3142.     VRScriptVariablePtr    myPointer = NULL;
  3143.  
  3144.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);    
  3145.     if (myAppData == NULL)
  3146.         return(NULL);
  3147.     
  3148.     // walk our linked list to find the target object
  3149.     myPointer = (VRScriptVariablePtr)(**myAppData).fListArray[kVREntry_Variable];
  3150.     while (myPointer != NULL) {
  3151.         if (strcmp(myPointer->fVarName, theVarName) == 0)
  3152.             return(myPointer);
  3153.         myPointer = myPointer->fNextEntry;
  3154.     }
  3155.     
  3156.     return(NULL);
  3157. }
  3158.  
  3159.  
  3160. //////////
  3161. //
  3162. // VRScript_InstallHotSpotInterceptProc
  3163. // Install an intercept procedure for handling hot spot triggerings.
  3164. //
  3165. //////////
  3166.  
  3167. void VRScript_InstallHotSpotInterceptProc (QTVRInstance theInstance, WindowObject theWindowObject)
  3168. {
  3169.     QTVRInterceptUPP        myInterceptProc;
  3170.     
  3171.     myInterceptProc = NewQTVRInterceptProc(VRScript_HotSpotInterceptProc);
  3172.     QTVRInstallInterceptProc(theInstance, kQTVRTriggerHotSpotSelector, myInterceptProc, (long)theWindowObject, 0);
  3173. }
  3174.  
  3175.  
  3176. //////////
  3177. //
  3178. // VRScript_InstallMouseOverHotSpotProc
  3179. // Install an intercept procedure for handling mouse-over hot spots.
  3180. //
  3181. //////////
  3182.  
  3183. void VRScript_InstallMouseOverHotSpotProc (QTVRInstance theInstance, WindowObject theWindowObject)
  3184. {
  3185.     QTVRMouseOverHotSpotUPP        myInterceptProc;
  3186.     
  3187.     myInterceptProc = NewQTVRMouseOverHotSpotProc(VRScript_MouseOverHotSpotProc);
  3188.     QTVRSetMouseOverHotSpotProc(theInstance, myInterceptProc, (long)theWindowObject, 0);
  3189. }
  3190.  
  3191.  
  3192. //////////
  3193. //
  3194. // VRScript_InstallPrescreenRoutine
  3195. // Install a prescreen buffer imaging complete procedure.
  3196. //
  3197. //////////
  3198.  
  3199. void VRScript_InstallPrescreenRoutine (QTVRInstance theInstance, WindowObject theWindowObject)
  3200. {
  3201.     ApplicationDataHdl    myAppData;
  3202.  
  3203.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3204.     if (myAppData != NULL)
  3205.         QTVRSetPrescreenImagingCompleteProc(theInstance, (**myAppData).fPrescreenProc, (SInt32)theWindowObject, 0);
  3206. }
  3207.  
  3208.  
  3209. //////////
  3210. //
  3211. // VRScript_InstallBackBufferImagingProc
  3212. // Install a back buffer imaging procedure.
  3213. // (This routine might sometimes be called to move or resize the area of interest within the panorama.)
  3214. //
  3215. //////////
  3216.  
  3217. void VRScript_InstallBackBufferImagingProc (QTVRInstance theInstance, WindowObject theWindowObject)
  3218. {
  3219.     ApplicationDataHdl        myAppData;
  3220.     QTVRAreaOfInterest        myArea;
  3221.     float                    myWidth, myHeight;
  3222.     VRScriptMoviePtr        myPointer;
  3223.     OSErr                    myErr = noErr;
  3224.     
  3225.     if ((theInstance == NULL) || (theWindowObject == NULL)) 
  3226.         return;
  3227.  
  3228.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3229.     if (myAppData == NULL) 
  3230.         return;
  3231.  
  3232.     HLock((Handle)myAppData);
  3233.     
  3234.     // remove any existing back buffer imaging procedure and dispose of its routine descriptor
  3235.     if ((**myAppData).fBackBufferProc != NULL)
  3236.         VRScript_RemoveBackBufferImagingProc((**theWindowObject).fInstance, theWindowObject);
  3237.  
  3238.     // create a new routine descriptor
  3239.     (**myAppData).fBackBufferProc = NewQTVRBackBufferImagingProc(VRScript_BackBufferImagingProc);
  3240.     
  3241.     // set the area of interest:
  3242.     // the application data structure holds the desired width, center, size, and scale of the movie
  3243.     myPointer = (VRScriptMoviePtr)(**myAppData).fListArray[kVREntry_QTMovie];
  3244.     if (myPointer == NULL) {
  3245.         myErr = paramErr;
  3246.         goto bail;
  3247.     }
  3248.     
  3249.     myWidth = myPointer->fMovieWidth * myPointer->fMovieScale;
  3250.     myHeight = myWidth * (((float)myPointer->fMovieRect.bottom) / ((float)myPointer->fMovieRect.right));
  3251.     
  3252.     if (myPointer->fUseMovieCenter) {
  3253.         // use the stored movie center
  3254.         myArea.panAngle = myPointer->fMovieCenter.x + (myWidth/2);
  3255.         myArea.tiltAngle = myPointer->fMovieCenter.y + (myHeight/2);
  3256.     } else {
  3257.         // center the movie on the current pan and tilt angles
  3258.         myArea.panAngle = QTVRGetPanAngle(theInstance) + (myWidth/2);
  3259.         myArea.tiltAngle = QTVRGetTiltAngle(theInstance) + (myHeight/2);
  3260.     }
  3261.     
  3262.     myArea.width = myWidth;
  3263.     myArea.height = myHeight;
  3264.     
  3265.     // *** insertion (B) ***
  3266.     
  3267.     // make sure we get called on every idle event, so we can keep playing the embedded movie;
  3268.     // also make sure we get called on every back buffer update
  3269.     if (myPointer->fCompositeMovie)
  3270.         myArea.flags = kQTVRBackBufferEveryIdle | kQTVRBackBufferEveryUpdate | kQTVRBackBufferHorizontal | kQTVRBackBufferAlwaysRefresh;
  3271.     else
  3272.         myArea.flags = kQTVRBackBufferEveryIdle | kQTVRBackBufferEveryUpdate | kQTVRBackBufferHorizontal;
  3273.             
  3274.     // install our procedure
  3275.     myErr = QTVRSetBackBufferImagingProc(theInstance, (**myAppData).fBackBufferProc, 1, &myArea, (SInt32)theWindowObject);
  3276.  
  3277. bail:
  3278.     // make sure we successfully installed the procedure;
  3279.     // if an error occurred, clear the saved routine descriptor.
  3280.     if (myErr != noErr)
  3281.         VRScript_RemoveBackBufferImagingProc((**theWindowObject).fInstance, theWindowObject);
  3282.     
  3283.     HUnlock((Handle)myAppData);
  3284. }
  3285.     
  3286.  
  3287. //////////
  3288. //
  3289. // VRScript_InstallInterceptRoutine
  3290. // Install our QTVR intercept procedure.
  3291. //
  3292. //////////
  3293.  
  3294. void VRScript_InstallInterceptRoutine (QTVRInstance theInstance, WindowObject theWindowObject)
  3295. {
  3296.     QTVRInterceptUPP    myInterceptProc;
  3297.     
  3298.     myInterceptProc = NewQTVRInterceptProc(VRScript_InterceptRoutine);    
  3299.     
  3300.     // we'll just use the same intercept proc for each intercepted procedure
  3301.     QTVRInstallInterceptProc(theInstance, kQTVRSetPanAngleSelector, myInterceptProc, (SInt32)theWindowObject, 0);
  3302.     QTVRInstallInterceptProc(theInstance, kQTVRSetTiltAngleSelector, myInterceptProc, (SInt32)theWindowObject, 0);
  3303.     QTVRInstallInterceptProc(theInstance, kQTVRSetFieldOfViewSelector, myInterceptProc, (SInt32)theWindowObject, 0);
  3304.     QTVRInstallInterceptProc(theInstance, kQTVRSetViewCenterSelector, myInterceptProc, (SInt32)theWindowObject, 0);
  3305. }
  3306.  
  3307.  
  3308. //////////
  3309. //
  3310. // VRScript_RemoveBackBufferImagingProc
  3311. // Remove the back buffer imaging procedure.
  3312. //
  3313. //////////
  3314.  
  3315. void VRScript_RemoveBackBufferImagingProc (QTVRInstance theInstance, WindowObject theWindowObject)
  3316. {
  3317.     ApplicationDataHdl        myAppData;
  3318.  
  3319.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3320.     if (myAppData == NULL) 
  3321.         return;
  3322.  
  3323.     // clear the existing back buffer imaging proc
  3324.     QTVRSetBackBufferImagingProc(theInstance, NULL, 0, NULL, 0);
  3325. #if TARGET_OS_MAC
  3326.     if ((**myAppData).fBackBufferProc != NULL)
  3327.         DisposeRoutineDescriptor((**myAppData).fBackBufferProc);
  3328. #endif
  3329.     (**myAppData).fBackBufferProc = NULL;
  3330. }
  3331.  
  3332.  
  3333. //////////
  3334. //
  3335. // VRScript_HotSpotInterceptProc
  3336. // An intercept procedure for handling hot spot triggerings.
  3337. //
  3338. //////////
  3339.  
  3340. PASCAL_RTN void VRScript_HotSpotInterceptProc (QTVRInstance theInstance, QTVRInterceptPtr theMsg, WindowObject theWindowObject, Boolean *theCancel)
  3341. {
  3342.     VRScriptClickHSPtr        myPointer;
  3343.     VRScriptClickHSPtr        myNext;
  3344.     ApplicationDataHdl        myAppData;
  3345.     UInt32                    myNodeID;
  3346.     UInt32                    myHotSpotID;
  3347.     OSType                    myType;
  3348.     Boolean                    myCancelLink = false;
  3349.     
  3350.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3351.     if (myAppData == NULL)
  3352.         return;
  3353.  
  3354.     myNodeID = QTVRGetCurrentNodeID(theInstance);
  3355.     myHotSpotID = (UInt32)(theMsg->parameter[0]);
  3356.     
  3357.     // get the type of the hot spot, given its ID
  3358.     QTVRUtils_GetHotSpotType(theInstance, myNodeID, myHotSpotID, &myType);
  3359.     
  3360.     // walk the linked list and find any commands for this hot spot
  3361.     myPointer = (VRScriptClickHSPtr)(**myAppData).fListArray[kVREntry_ClickHS];
  3362.     while (myPointer != NULL) {
  3363.         myNext = myPointer->fNextEntry;
  3364.         
  3365.         if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode))
  3366.             if (((myPointer->fSelectByID) && (myPointer->fHotSpotID == myHotSpotID))    // hot spot is specified by ID
  3367.             || ((!myPointer->fSelectByID) && (myPointer->fHotSpotType == myType))) {    // hot spot is specified by type
  3368.                 if (myPointer->fOptions != 0)
  3369.                     myCancelLink = true;
  3370.                 VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3371.                 VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3372.             }
  3373.  
  3374.         myPointer = myNext;
  3375.     }
  3376.  
  3377.     *theCancel = myCancelLink;
  3378. }
  3379.  
  3380.  
  3381. ///////////
  3382. //
  3383. // VRScript_PrescreenRoutine
  3384. // A prescreen buffer imaging completion routine:
  3385. //     * alter the position of the 3D sound listener based on the user's panning or tilting
  3386. //     * set balance and volume of embedded QuickTime movie
  3387. //    * draw the rendered 3D scene into the prescreen buffer
  3388. //    * draw any enlisted overlay picture into the prescreen buffer
  3389. //
  3390. //////////
  3391.  
  3392. PASCAL_RTN OSErr VRScript_PrescreenRoutine (QTVRInstance theInstance, WindowObject theWindowObject)
  3393. {
  3394.     float                myPan;
  3395.     float                myTilt;
  3396.     float                myFOV;
  3397.     UInt32                myNodeID;
  3398.     ApplicationDataHdl    myAppData;
  3399.  
  3400.     // get the application-specific data associated with the window
  3401.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3402.     if (myAppData == NULL)
  3403.         return(paramErr);
  3404.         
  3405.     // get the current environment
  3406.     myPan = QTVRGetPanAngle(theInstance);
  3407.     myTilt = QTVRGetTiltAngle(theInstance);
  3408.     myFOV = QTVRGetFieldOfView(theInstance);
  3409.     myNodeID = QTVRGetCurrentNodeID(theInstance);
  3410.  
  3411.     // process any localized sounds in the current node
  3412.     if ((**myAppData).fViewHasChanged || (**myAppData).fSoundHasChanged) 
  3413.         if ((**myAppData).fListArray[kVREntry_Sound] != NULL) {
  3414.             if (gHasSoundSprockets) {
  3415. #if SOUNDSPROCKET_AVAIL
  3416.                 TQ3Vector3D            myOrientation;
  3417.             
  3418.                 // figure out the orientation    
  3419.                 myOrientation.x = -sin(myPan) * cos(myTilt);
  3420.                 myOrientation.y = sin(myTilt);
  3421.                 myOrientation.z = -cos(myPan) * cos(myTilt);
  3422.                     
  3423.                 // set the new orientation of the listener
  3424.                 SSpListener_SetOrientation((**myAppData).fListener, &myOrientation);
  3425.                 // update the virtual audio environment
  3426.                 VRSound_Update3DSoundEnv(theWindowObject);
  3427. #endif
  3428.             } else {
  3429.                 // we don't have SoundSprockets, so....
  3430.                 // handle sound balance and volume attentuation ourselves
  3431.                 VRSound_SetBalanceAndVolume(theWindowObject, myPan, myTilt);
  3432.             }
  3433.         }
  3434.         
  3435. #if QD3D_AVAIL
  3436.     // process any 3D objects in the current node
  3437.     if (gHasQuickDraw3D)
  3438.         if ((**myAppData).fListArray[kVREntry_QD3DObject] != NULL)
  3439.             VR3DObjects_PrescreenRoutine(theInstance, theWindowObject);
  3440. #endif
  3441.  
  3442.     // handle directionality and volume attenuation for QuickTime movie sound and texture-mapped QuickTime movie sound
  3443.     if ((**myAppData).fViewHasChanged || (**myAppData).fSoundHasChanged)
  3444.         if (((**myAppData).fListArray[kVREntry_QTMovie] != NULL) || ((**myAppData).fListArray[kVREntry_QD3DObject] != NULL))
  3445.             VRMoov_SetAllBalanceAndVolume(theWindowObject, myPan, myTilt);
  3446.  
  3447.     // draw any overlay pictures
  3448.     VRPicture_DrawNodePictures(theWindowObject);
  3449.  
  3450.     // reset our flags
  3451.     (**myAppData).fViewHasChanged = false;
  3452.     (**myAppData).fSoundHasChanged = false;
  3453.     
  3454.     return(noErr);
  3455. }
  3456.  
  3457.  
  3458. //////////
  3459. //
  3460. // VRScript_BackBufferImagingProc
  3461. // A back buffer imaging procedure:
  3462. //    * handle any QuickTime movies playing in the back buffer
  3463. //    * handle any pictures embedded in the back buffer [to be provided]
  3464. //
  3465. //////////
  3466.  
  3467. PASCAL_RTN OSErr VRScript_BackBufferImagingProc (QTVRInstance theInstance, Rect *theRect, UInt16 theAreaIndex, UInt32 theFlagsIn, UInt32 *theFlagsOut, WindowObject theWindowObject)
  3468. {
  3469. #pragma unused(theAreaIndex)
  3470.  
  3471.     ApplicationDataHdl        myAppData;
  3472.     OSErr                    myErr = noErr;
  3473.     
  3474.     if ((theInstance == NULL) || (theWindowObject == NULL)) 
  3475.         return(paramErr);
  3476.  
  3477.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3478.     if (myAppData == NULL) 
  3479.         return(paramErr);
  3480.  
  3481.     // if we've got an active movie to play, do so
  3482.     if (VRMoov_GetEmbeddedVideo(theWindowObject) != NULL)
  3483.         myErr = VRMoov_BackBufferImagingProc(theInstance, theRect, theAreaIndex, theFlagsIn, theFlagsOut, theWindowObject);
  3484.             
  3485.     return(myErr);
  3486. }
  3487.  
  3488.  
  3489. //////////
  3490. //
  3491. // VRScript_InterceptRoutine
  3492. // An intercept routine:
  3493. //     * signal that the view parameters have changed
  3494. //
  3495. //////////
  3496.  
  3497. PASCAL_RTN void VRScript_InterceptRoutine (QTVRInstance theInstance, QTVRInterceptPtr theMsg, WindowObject theWindowObject, Boolean *cancel)
  3498. {
  3499. #pragma unused(theInstance)
  3500.  
  3501.     Boolean                myCancelInterceptedProc = false;    // true == do NOT call thru; false == call thru
  3502.     ApplicationDataHdl    myAppData;
  3503.     
  3504.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3505.     if (myAppData == NULL)
  3506.         return;
  3507.  
  3508.     switch (theMsg->selector) {
  3509.         case kQTVRSetPanAngleSelector:
  3510.         case kQTVRSetTiltAngleSelector:
  3511.         case kQTVRSetFieldOfViewSelector:
  3512.         case kQTVRSetViewCenterSelector:
  3513.             (**myAppData).fViewHasChanged = true;
  3514.             break;
  3515.             
  3516.         default:
  3517.             break;
  3518.     }
  3519.     
  3520.     *cancel = myCancelInterceptedProc;
  3521. }
  3522.  
  3523.  
  3524. //////////
  3525. //
  3526. // VRScript_EnteringNodeProc
  3527. // A node-entering procedure:
  3528. //    * initialize node-specific global variables (e.g., the node timer)
  3529. //    * execute the standard node-entry procedure
  3530. //    * execute any node-entry commands
  3531. //    * execute any custom transitions from the previous node to the current node
  3532. //
  3533. //////////
  3534.  
  3535. PASCAL_RTN OSErr VRScript_EnteringNodeProc (QTVRInstance theInstance, UInt32 theNodeID, WindowObject theWindowObject)
  3536. {
  3537.     VRScriptNodeInPtr        myPointer = NULL;
  3538.     VRScriptNodeInPtr        myNext = NULL;
  3539.     ApplicationDataHdl        myAppData;
  3540.  
  3541.     // initialize our node timer
  3542.     gNodeStartingTime = TickCount();
  3543.  
  3544.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3545.     if (myAppData == NULL)
  3546.         return(paramErr);
  3547.  
  3548.     // call the standard node-entry procedure
  3549.     if ((**theWindowObject).fController != NULL)
  3550.         QTVRUtils_StandardEnteringNodeProc(theInstance, theNodeID, (**theWindowObject).fController);
  3551.  
  3552.     // node-entry commands might invoke QTVRUpdate, so enable update-streaming
  3553.     if (QTVRUtils_IsPanoNode(theInstance))
  3554.         QTVRBeginUpdateStream(theInstance, kQTVRCurrentMode);
  3555.  
  3556.     // walk the node-entry command list and execute any that apply to this node
  3557.     myPointer = (VRScriptNodeInPtr)(**myAppData).fListArray[kVREntry_NodeEntry];
  3558.     while (myPointer != NULL) {
  3559.         myNext = myPointer->fNextEntry;
  3560.         
  3561.         if ((myPointer->fNodeID == theNodeID) || (myPointer->fNodeID == kVRAnyNode)) {
  3562.             VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3563.             VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3564.         }
  3565.     
  3566.         myPointer = myNext;
  3567.     }
  3568.     
  3569.     // disable update-streaming, if previously enabled
  3570.     if (QTVRUtils_IsPanoNode(theInstance))
  3571.         QTVREndUpdateStream(theInstance);
  3572.  
  3573.     // if a node transition effect is pending, force the movie image to be updated;
  3574.     // this draws the destination image into an offscreen GWorld
  3575.     if ((**myAppData).fActiveTransition != NULL) {
  3576.         MoviesTask((**theWindowObject).fMovie, 0L);
  3577.         
  3578.         // execute any custom transitions from the previous node to the current node
  3579.         if (gHasQTVideoEffects)
  3580.             VREffects_RunTransitionEffect(theWindowObject);
  3581.     }
  3582.  
  3583.     return(noErr);
  3584. }
  3585.  
  3586.  
  3587. //////////
  3588. //
  3589. // VRScript_LeavingNodeProc
  3590. // A node-leaving procedure:
  3591. //    * execute any node-exit commands
  3592. //    * stop any sounds attached to the current node
  3593. //    * dump any pictures attached to the current node
  3594. //    * dump any movies attached to the current node
  3595. //    * dump any unexpired AtTime commands that shouldn't be orphaned
  3596. //    * set up for any custom transitions from the current node to the target node
  3597.  
  3598. //////////
  3599.  
  3600. PASCAL_RTN OSErr VRScript_LeavingNodeProc (QTVRInstance theInstance, UInt32 fromNodeID, UInt32 toNodeID, Boolean *theCancel, WindowObject theWindowObject)
  3601. {
  3602.     VRScriptNodeOutPtr        myPointer;
  3603.     VRScriptNodeOutPtr        myNext;
  3604.     ApplicationDataHdl        myAppData;
  3605.     Boolean                    myCancelExit = false;
  3606.     
  3607.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3608.     if (myAppData == NULL)
  3609.         return(paramErr);
  3610.         
  3611.     // walk the node-leaving command list and execute any that apply to this node
  3612.     myPointer = (VRScriptNodeOutPtr)(**myAppData).fListArray[kVREntry_NodeExit];
  3613.     while (myPointer != NULL) {
  3614.         myNext = myPointer->fNextEntry;
  3615.         
  3616.         if ((myPointer->fFromNodeID == fromNodeID) || (myPointer->fFromNodeID == kVRAnyNode))
  3617.             if ((myPointer->fToNodeID == toNodeID) || (myPointer->fToNodeID == kVRAnyNode)) {
  3618.                 VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3619.                 if (myPointer->fOptions != 0)
  3620.                     myCancelExit = true;
  3621.                 VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3622.             }
  3623.     
  3624.         myPointer = myNext;
  3625.     }
  3626.     
  3627.     // set output parameter to indicate whether we're leaving the node or not
  3628.     *theCancel = myCancelExit;
  3629.     
  3630.     // if we're not leaving the node, just return
  3631.     if (myCancelExit)
  3632.         return(noErr);
  3633.     
  3634.     // set up for any custom transitions from the current node to the target node
  3635.     // (since we're going to get the first frame of our effect by rendering a frame
  3636.     // of the movie into an offscreen GWorld, we need to do this before we dump the
  3637.     // node pictures, movies, etc.)
  3638.     if (gHasQTVideoEffects)
  3639.         VREffects_SetupTransitionEffect(theWindowObject, fromNodeID, toNodeID);
  3640.     
  3641.     // if we really are leaving the node, dump node-specific sounds, pictures, and movies
  3642.     VRSound_DumpNodeSounds(theWindowObject);
  3643.     VRPicture_DumpNodePictures(theWindowObject);
  3644.     VRMoov_DumpNodeMovies(theWindowObject);
  3645.     
  3646.     // dump any unexpired time-based commands that are marked as to-be-killed
  3647.     VRScript_DumpUnexpiredCommands(theWindowObject, fromNodeID);
  3648.     
  3649.     // work around a bug in QTVR: 
  3650.     // moving from a panoramic node to an object node effectively hoses the prescreen routine,
  3651.     // so we need to reinstall that routine if we're moving from an object to a panoramic node
  3652.     if (QTVRGetNodeType(theInstance, fromNodeID) == kQTVRObjectType)
  3653.         if (QTVRGetNodeType(theInstance, toNodeID) == kQTVRPanoramaType)
  3654.             VRScript_InstallPrescreenRoutine(theInstance, theWindowObject);
  3655.  
  3656.     return(noErr);
  3657. }
  3658.  
  3659.  
  3660. //////////
  3661. //
  3662. // VRScript_MouseOverHotSpotProc
  3663. // Walk through our linked list of mouse-over hot spot commands and see whether any need to be executed.
  3664. //
  3665. // We support hot spots specified by ID (myPointer->fSelectByID == true) or by type (myPointer->fSelectByID == false).
  3666. //
  3667. //////////
  3668.  
  3669. PASCAL_RTN OSErr VRScript_MouseOverHotSpotProc (QTVRInstance theInstance, UInt32 theHotSpotID, UInt32 theFlags, WindowObject theWindowObject)
  3670. {
  3671.     VRScriptAtMOHSPtr        myPointer;
  3672.     VRScriptAtMOHSPtr        myNext;
  3673.     ApplicationDataHdl        myAppData;
  3674.     UInt32                    myNodeID;
  3675.     OSType                    myType;
  3676.     
  3677.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3678.     if (myAppData == NULL)
  3679.         return(paramErr);
  3680.     
  3681.     // get the current node ID
  3682.     myNodeID = QTVRGetCurrentNodeID(theInstance);
  3683.     
  3684.     // get the type of the hot spot, given its ID
  3685.     QTVRUtils_GetHotSpotType(theInstance, myNodeID, theHotSpotID, &myType);
  3686.     
  3687.     // walk the linked list and find any commands for this hot spot
  3688.     myPointer = (VRScriptAtMOHSPtr)(**myAppData).fListArray[kVREntry_MouseOverHS];
  3689.     while (myPointer != NULL) {
  3690.         myNext = myPointer->fNextEntry;
  3691.         
  3692.         if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode))
  3693.             if (((myPointer->fSelectByID) && (myPointer->fHotSpotID == theHotSpotID))    // hot spot is specified by ID
  3694.             || ((!myPointer->fSelectByID) && (myPointer->fHotSpotType == myType)))        // hot spot is specified by type
  3695.                 if (myPointer->fOptions == theFlags) {
  3696.                     VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3697.                     VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3698.                 }
  3699.     
  3700.         myPointer = myNext;
  3701.     }
  3702.  
  3703.     return(noErr);        // returning noErr means QTVR should do its normal mouse-over-hot-spot stuff
  3704. }
  3705.  
  3706.  
  3707. //////////
  3708. //
  3709. // VRScript_MoviePrePrerollCompleteProc
  3710. // A completion procedure for pre-prerolling movies.
  3711. //
  3712. //////////
  3713.  
  3714. PASCAL_RTN void VRScript_MoviePrePrerollCompleteProc (Movie theMovie, OSErr thePrerollErr, void *theRefcon)
  3715. {
  3716. #pragma unused(thePrerollErr, theRefcon)
  3717.     
  3718.     PrerollMovie(theMovie, 0, GetMoviePreferredRate(theMovie));
  3719.     StartMovie(theMovie);
  3720. }
  3721.  
  3722.  
  3723. //////////
  3724. //
  3725. // VRScript_CheckForTimedCommands
  3726. // Walk through our linked list of timed commands and see whether any need to be executed.
  3727. //
  3728. //////////
  3729.  
  3730. void VRScript_CheckForTimedCommands (WindowObject theWindowObject)
  3731. {
  3732.     ApplicationDataHdl        myAppData;
  3733.     UInt32                    myNodeID;
  3734.     VRScriptAtTimePtr        myPointer;
  3735.     VRScriptAtTimePtr        myNext;
  3736.     Boolean                    myRunCommand;
  3737.  
  3738.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3739.     if (myAppData == NULL)
  3740.         return;
  3741.  
  3742.     myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  3743.     
  3744.     // walk the linked list and find any commands ready to be executed
  3745.     myPointer = (VRScriptAtTimePtr)(**myAppData).fListArray[kVREntry_TimedCommand];
  3746.     while (myPointer != NULL) {
  3747.         myNext = myPointer->fNextEntry;
  3748.         myRunCommand = false;
  3749.  
  3750.         switch (myPointer->fMode) {
  3751.             case kVRUseNodeTime:
  3752.                 if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode))
  3753.                     myRunCommand = (gNodeElapsedTime >= myPointer->fTime);
  3754.                 break;
  3755.             case kVRUseAbsoluteTime:
  3756.                 myRunCommand = (gAbsoluteElapsedTime >= myPointer->fTime);
  3757.                 break;
  3758.             case kVRUseInstallTime:
  3759.                 myRunCommand = ((gAbsoluteElapsedTime - myPointer->fTimeInstalled) >= myPointer->fTime);
  3760.                 break;
  3761.         }
  3762.  
  3763.         if (myRunCommand) {
  3764.             VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3765.             if (myPointer->fRepeat) {
  3766.                 myPointer->fTime += myPointer->fPeriod;
  3767.                 VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3768.             } else {
  3769.                 VRScript_DelistEntry(theWindowObject, (VRScriptGenericPtr)myPointer);
  3770.             }
  3771.         }
  3772.         
  3773.         myPointer = myNext;
  3774.     }
  3775. }
  3776.  
  3777.  
  3778. //////////
  3779. //
  3780. // VRScript_CheckForClickCustomButtonCommands
  3781. // Walk through our linked list of custom-button-click commands and see whether any need to be executed.
  3782. //
  3783. //////////
  3784.  
  3785. void VRScript_CheckForClickCustomButtonCommands (WindowObject theWindowObject, EventRecord *theEvent)
  3786. {
  3787.     ApplicationDataHdl        myAppData;
  3788.     UInt32                    myNodeID;
  3789.     VRScriptClickCustomPtr    myPointer = NULL;
  3790.     VRScriptClickCustomPtr    myNext = NULL;
  3791.     UInt32                    myStartTicks = theEvent->when;
  3792.     UInt32                    myElapsedTime = 0;
  3793.     UInt32                    myIgnoredTime;
  3794.     
  3795.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3796.     if (myAppData == NULL)
  3797.         return;
  3798.  
  3799.     myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  3800.     
  3801.     // walk the custom-button-click command linked list and execute any that apply to this node
  3802.     myPointer = (VRScriptClickCustomPtr)(**myAppData).fListArray[kVREntry_ClickCustom];
  3803.     while (myPointer != NULL) {
  3804.         myNext = myPointer->fNextEntry;
  3805.         
  3806.         if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode)) {
  3807.             VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3808.             VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3809.         }
  3810.     
  3811.         myPointer = myNext;
  3812.     }
  3813.     
  3814.     // we want the button to be depressed for at least kMyButtonDelay ticks, so (perhaps) let's wait before returning
  3815.     myElapsedTime = TickCount() - myStartTicks;
  3816.     if (myElapsedTime < kMyButtonDelay)
  3817.         Delay(kMyButtonDelay - myElapsedTime, &myIgnoredTime);
  3818. }
  3819.  
  3820.  
  3821. //////////
  3822. //
  3823. // VRScript_CheckForClickSpriteCommands
  3824. // Determine whether a mouse click is on a sprite; return true if it is, false otherwise.
  3825. //
  3826. // This routine is intended to be called from your movie controller action filter function,
  3827. // in response to mcActionMouseDown actions.
  3828. //
  3829. //////////
  3830.  
  3831. Boolean VRScript_CheckForClickSpriteCommands (WindowObject theWindowObject, EventRecord *theEvent)
  3832. {
  3833.     ApplicationDataHdl        myAppData;
  3834.     MediaHandler            myHandler = NULL;
  3835.     Boolean                    isHandled = false;
  3836.     long                    myFlags = 0L;
  3837.     QTAtomID                myAtomID = 0;
  3838.     Point                    myPoint;
  3839.     UInt32                    myNodeID;
  3840.     VRScriptClickSpritePtr    myPointer = NULL;
  3841.     VRScriptClickSpritePtr    myNext = NULL;
  3842.     ComponentResult            myErr = noErr;
  3843.     
  3844.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3845.     if (myAppData == NULL)
  3846.         goto bail;
  3847.  
  3848.     if (theEvent == NULL)
  3849.         goto bail;
  3850.         
  3851.     myHandler = (**myAppData).fSpriteHandler;
  3852.     myFlags = spriteHitTestImage | spriteHitTestLocInDisplayCoordinates | spriteHitTestInvisibleSprites;
  3853.     myPoint = theEvent->where;
  3854.     myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  3855.     
  3856.     myErr = SpriteMediaHitTestAllSprites(myHandler, myFlags, myPoint, &myAtomID);
  3857.     if ((myErr == noErr) && (myAtomID != 0)) {
  3858.         
  3859.         // the user has clicked on a sprite;
  3860.         // walk the sprite-click command linked list and execute any that apply to that sprite in this node
  3861.         myPointer = (VRScriptClickSpritePtr)(**myAppData).fListArray[kVREntry_ClickSprite];
  3862.         while (myPointer != NULL) {
  3863.             myNext = myPointer->fNextEntry;
  3864.             
  3865.             if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode)) {
  3866.                 if ((myPointer->fOptions == myAtomID) || (myPointer->fOptions == kVRAnySprite)) {
  3867.                     VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3868.                     VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3869.                 }
  3870.             }
  3871.         
  3872.             myPointer = myNext;
  3873.         }
  3874.  
  3875.         isHandled = true;
  3876.     }
  3877.     
  3878. bail:
  3879.     return(isHandled);
  3880. }
  3881.  
  3882.  
  3883. //////////
  3884. //
  3885. // VRScript_CheckForAngleCommands
  3886. // Walk through our linked lists of angle-triggered commands and see whether any need to be executed.
  3887. //
  3888. //////////
  3889.  
  3890. void VRScript_CheckForAngleCommands (WindowObject theWindowObject)
  3891. {
  3892.     ApplicationDataHdl        myAppData;
  3893.     VRScriptAtAnglePtr        myNext;
  3894.     VRScriptAtAnglePtr        myPointer;
  3895.     UInt32                    myNodeID;
  3896.     float                    myPan;
  3897.     float                    myTilt;
  3898.     float                    myFOV;
  3899.  
  3900.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3901.     if (myAppData == NULL)
  3902.         return;
  3903.         
  3904.     // get the current environment
  3905.     myPan = QTVRGetPanAngle((**theWindowObject).fInstance);
  3906.     myTilt = QTVRGetTiltAngle((**theWindowObject).fInstance);
  3907.     myFOV = QTVRGetFieldOfView((**theWindowObject).fInstance);
  3908.     myNodeID = QTVRGetCurrentNodeID((**theWindowObject).fInstance);
  3909.  
  3910.     // walk the pan angle linked list
  3911.     myPointer = (VRScriptAtAnglePtr)(**myAppData).fListArray[kVREntry_PanAngleCmd];
  3912.     while (myPointer != NULL) {
  3913.         myNext = myPointer->fNextEntry;
  3914.  
  3915.         if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode))
  3916.             if (myPointer->fMinAngle <= myPan)
  3917.                 if (myPointer->fMaxAngle >= myPan) {
  3918.                     VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3919.                     VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3920.                 }
  3921.         myPointer = myNext;
  3922.     }
  3923.  
  3924.     // walk the tilt angle linked list
  3925.     myPointer = (VRScriptAtAnglePtr)(**myAppData).fListArray[kVREntry_TiltAngleCmd];
  3926.     while (myPointer != NULL) {
  3927.         myNext = myPointer->fNextEntry;
  3928.  
  3929.         if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode))
  3930.             if (myPointer->fMinAngle <= myTilt)
  3931.                 if (myPointer->fMaxAngle >= myTilt) {
  3932.                     VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3933.                     VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3934.                 }
  3935.         myPointer = myNext;
  3936.     }
  3937.  
  3938.     // walk the zoom angle linked list
  3939.     myPointer = (VRScriptAtAnglePtr)(**myAppData).fListArray[kVREntry_FOVAngleCmd];
  3940.     while (myPointer != NULL) {
  3941.         myNext = myPointer->fNextEntry;
  3942.  
  3943.         if ((myPointer->fNodeID == myNodeID) || (myPointer->fNodeID == kVRAnyNode))
  3944.             if (myPointer->fMinAngle <= myFOV)
  3945.                 if (myPointer->fMaxAngle >= myFOV) {
  3946.                     VRScript_ProcessScriptCommandLine(theWindowObject, myPointer->fCommandLine);
  3947.                     VRScript_CheckForExpiredCommand(theWindowObject, (VRScriptGenericPtr)myPointer);
  3948.                 }
  3949.         myPointer = myNext;
  3950.     }
  3951.  
  3952. }
  3953.  
  3954.  
  3955. //////////
  3956. //
  3957. // VRScript_CheckForExpiredCommand
  3958. // See whether the specified command entry has expired.
  3959. //
  3960. //////////
  3961.  
  3962. void VRScript_CheckForExpiredCommand (WindowObject theWindowObject, VRScriptGenericPtr thePointer)
  3963. {
  3964.     if (thePointer->fMaxExecutions != kVRDoIt_Forever)
  3965.         thePointer->fMaxExecutions--;
  3966.     if (thePointer->fMaxExecutions == 0)
  3967.         VRScript_DelistEntry(theWindowObject, (VRScriptGenericPtr)thePointer);
  3968. }
  3969.  
  3970.  
  3971. //////////
  3972. //
  3973. // VRScript_DumpUnexpiredCommands
  3974. // Dump any unexpired AtTime commands, if the list entry so indicates.
  3975. // This is called only when leaving a node, to removed unexecuted ("orphaned") commands
  3976. // which would be executed the next time the user entered the node.
  3977. //
  3978. //////////
  3979.  
  3980. void VRScript_DumpUnexpiredCommands (WindowObject theWindowObject, UInt32 theNodeID)
  3981. {
  3982.     ApplicationDataHdl        myAppData;
  3983.     VRScriptAtTimePtr        myPointer;
  3984.     VRScriptAtTimePtr        myNext;
  3985.  
  3986.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  3987.     if (myAppData == NULL)
  3988.         return;
  3989.  
  3990.     // walk the linked list of timed commands and find any commands to be removed from list
  3991.     myPointer = (VRScriptAtTimePtr)(**myAppData).fListArray[kVREntry_TimedCommand];
  3992.     while (myPointer != NULL) {
  3993.         myNext = myPointer->fNextEntry;
  3994.  
  3995.         if (myPointer->fNodeID == theNodeID)
  3996.             if (myPointer->fOptions == kVROrphan_Kill)
  3997.                 VRScript_DelistEntry(theWindowObject, (VRScriptGenericPtr)myPointer);
  3998.         
  3999.         myPointer = myNext;
  4000.     }
  4001. }
  4002.  
  4003.  
  4004. //////////
  4005. //
  4006. // VRScript_PackString
  4007. // Pack a string.
  4008. //
  4009. //////////
  4010.  
  4011. void VRScript_PackString (char *theString)
  4012. {
  4013.     short        myLength;
  4014.     short        myIndex;
  4015.     
  4016.     myLength = strlen(theString);
  4017.     for (myIndex = 0; myIndex < myLength; myIndex++)
  4018.         if (isspace(theString[myIndex]))
  4019.             theString[myIndex] = '#';
  4020. }
  4021.  
  4022.  
  4023. //////////
  4024. //
  4025. // VRScript_UnpackString
  4026. // Unpack a string (for instance, to make a packed command line suitable for parsing by VRScript_ProcessScriptCommandLine).
  4027. //
  4028. // We allow embedding commands in other commands: '*' -> '&' -> '%' -> '#' -> ' '
  4029. //
  4030. //////////
  4031.  
  4032. void VRScript_UnpackString (char *theString)
  4033. {
  4034.     short        myLength;
  4035.     short        myIndex;
  4036.     
  4037.     myLength = strlen(theString);
  4038.     for (myIndex = 0; myIndex < myLength; myIndex++) {
  4039.         if (theString[myIndex] == '#')
  4040.             theString[myIndex] = ' ';
  4041.         if (theString[myIndex] == '%')
  4042.             theString[myIndex] = '#';
  4043.         if (theString[myIndex] == '&')
  4044.             theString[myIndex] = '%';
  4045.         if (theString[myIndex] == '*')
  4046.             theString[myIndex] = '&';
  4047.     }
  4048. }
  4049.  
  4050.  
  4051. //////////
  4052. //
  4053. // VRScript_DecodeString
  4054. // Decode a string, assumed to have been encoded using a simple rotate-11 scheme.
  4055. //
  4056. //////////
  4057.  
  4058. void VRScript_DecodeString (char *theString)
  4059. {
  4060.     short        myLength;
  4061.     short        myIndex;
  4062.     
  4063.     myLength = strlen(theString);
  4064.     for (myIndex = 0; myIndex < myLength; myIndex++)
  4065.         if (theString[myIndex] != '\n')
  4066.             theString[myIndex] = theString[myIndex] - 11;
  4067. }
  4068.  
  4069.  
  4070. //////////
  4071. //
  4072. // VRScript_StringToOSType
  4073. // Convert a string to an OSType.
  4074. //
  4075. //////////
  4076.  
  4077. OSType VRScript_StringToOSType (char *theString)
  4078. {
  4079.     unsigned long        myType = 0L;
  4080.     
  4081.     if (strlen(theString) < kMaxOSTypeLength - 1)
  4082.         return((OSType)myType);
  4083.         
  4084.     myType += theString[3] << 0;
  4085.     myType += theString[2] << 8;
  4086.     myType += theString[1] << 16;
  4087.     myType += theString[0] << 24;
  4088.     
  4089.     return((OSType)myType);
  4090. }
  4091.  
  4092.  
  4093. //////////
  4094. //
  4095. // VRScript_OSTypeToString
  4096. // Convert an OSType to a string.
  4097. //
  4098. // The caller is responsible for disposing of the pointer returned by this function (by calling free).
  4099. //
  4100. //////////
  4101.  
  4102. char *VRScript_OSTypeToString (OSType theType)
  4103. {
  4104.     char            *myString = malloc(kMaxOSTypeLength);
  4105.     
  4106.     if (myString == NULL)
  4107.         return(NULL);
  4108.         
  4109.     myString[0] = (theType & 0xff000000) >> 24;
  4110.     myString[1] = (theType & 0x00ff0000) >> 16;
  4111.     myString[2] = (theType & 0x0000ff00) >> 8;
  4112.     myString[3] = (theType & 0x000000ff) >> 0;
  4113.     myString[4] = '\0';
  4114.     
  4115.     return(myString);
  4116. }
  4117.  
  4118.  
  4119. //////////
  4120. //
  4121. // VRScript_FloatsAreEqual
  4122. // Are the specified floating-point numbers equal, within a specified tolerance?
  4123. //
  4124. //////////
  4125.  
  4126. Boolean VRScript_FloatsAreEqual (float theFloat1, float theFloat2, float theTolerance)
  4127. {
  4128.     Boolean            areEqual = false;
  4129.     float            myDifference;
  4130.     
  4131.     myDifference = theFloat1 - theFloat2;
  4132.     if (myDifference < 0.0)
  4133.         myDifference *= -1.0;
  4134.     
  4135.     if (myDifference <= theTolerance)
  4136.         areEqual = true;
  4137.     
  4138.     return(areEqual);
  4139. }